Developers

API & webhooks

Send us completed jobs, appointments or purchases. We handle eligibility, scheduling, delivery, follow-ups and stop rules.

Authentication

REST API (Pro): create a key under Integrations and send Authorization: Bearer syr_live_….

Inbound webhook (Growth & Pro): create a webhook to get a URL and signing secret. Sign each request with X-SYR-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">. Requests older than 5 minutes are rejected (replay protection). Tools that can't sign may send X-SYR-Token: <secret>.

Endpoints

  • POST /api/v1/completions — API key
  • POST /api/hooks/<webhook-id> — signed webhook
  • GET /api/v1/locations — API key; lists your location IDs

Payload

{
  "event_id": "job-10293",
  "event_type": "job_completed",
  "completed_at": "2026-11-11T15:30:00Z",
  "location_id": "6f1c…",
  "customer": {
    "first_name": "Alex",
    "last_name": "Rivera",
    "email": "alex@example.com",
    "phone": "+15125550123",
    "external_id": "C-881",
    "sms_consent": { "granted": true, "consented_at": "2026-11-02T10:04:00Z", "method": "booking form checkbox" }
  }
}

event_type is one of job_completed, appointment_completed, purchase_completed, order_fulfilled, service_delivered, invoice_paid. Either customer.email or customer.phone is required.

Text-message consent

Texts are sent only to customers whose consent to receive texts from your business is on record. Send customer.sms_consent as true, or as an object with granted, an optional consented_at (ISO-8601) and an optional method describing how consent was collected. Each value is stored in an auditable consent log. Without it the customer can still receive email. A customer who replied STOP can only opt back in themselves (by replying START) — sending sms_consent never overrides an opt-out.

Idempotency

event_id must be unique per completed job. Sending the same id again returns 200 with "outcome": "duplicate_event" and never sends a second request. A new event is accepted with 202.

Outcomes

enrolled, duplicate_event, already_in_sequence, cooldown, suppressed, no_reachable_channel, too_old (completed more than 30 days ago), no_active_automation, trigger_not_enabled, over_quota, subscription_inactive.

Rate limits

300 requests per minute per key and 600 per minute per webhook. Exceeding them returns 429.