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 keyPOST /api/hooks/<webhook-id>— signed webhookGET /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.