helpAPI Reference

OnSync exposes a REST API so you can move data between your CRM, data warehouse, and the shared inbox without waiting on UI features. Every endpoint shares the same base URL, returns JSON, and respects the same authentication model as your Zapier integration.

Base URL & versioning

Base URL: https://api.onsync.com/v1
Content-Type: application/json
  • Versioning happens in the URL (/v1). Backwards-incompatible changes ship under /v2.
  • All responses include requestId and timestamp fields for easier log correlation.

Authentication & rate limits

  1. Visit Settings -> API & Webhooks and click Generate Key. Keys use the format onsync_pk_live_xxx.
  2. Send the key via the Authorization header.
  3. Rotate keys quarterly and revoke unused credentials immediately.
Authorization: Bearer onsync_pk_live_xxx
  • Rate limit: 1,000 requests per org per hour (burst-friendly). Enterprise plans can request higher ceilings through support.
  • 4xx errors count toward the limit; retries with identical payloads should be spaced to avoid loops.

Contacts API

POST /contacts

Create or update a contact. OnSync deduplicates by phone, email, or externalId.

curl -X POST https://api.onsync.com/v1/contacts \
  -H "Authorization: Bearer $ONSYNC_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Sara",
    "lastName": "Hussein",
    "phone": "+971500000000",
    "email": "sara@example.com",
    "tags": ["lead", "expo"],
    "channel": "instagram",
    "properties": {
      "source": "Expo booth",
      "language": "en",
      "externalId": "crm_8740"
    }
  }'

Response

{
  "id": "contact_01JGDNWSW9",
  "firstName": "Sara",
  "phone": "+971500000000",
  "tags": ["lead", "expo"],
  "properties": {
    "source": "Expo booth",
    "language": "en",
    "externalId": "crm_8740"
  },
  "orgId": "org_123",
  "createdAt": "2024-12-01T10:00:00.000Z"
}

GET /contacts/{id} returns the same payload plus activity metadata. PATCH /contacts/{id} accepts any subset of the fields shown above.

Messaging API

POST /messaging/send

Send a WhatsApp, Instagram, Facebook, or Telegram message from the shared inbox. OnSync applies the same routing rules used in the UI, so Smart Triggers, AI Agent summaries, and assignments still fire.

curl -X POST https://api.onsync.com/v1/messaging/send \
  -H "Authorization: Bearer $ONSYNC_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "whatsapp",
    "to": "+971500000000",
    "messageType": "text",
    "content": "Welcome to OnSync. Reply STOP to unsubscribe.",
    "metadata": {
      "source": "api",
      "campaign": "expo-follow-up"
    }
  }'

Template messages:

{
  "platform": "whatsapp",
  "to": "+971500000000",
  "messageType": "template",
  "metadata": {
    "template": {
      "name": "order_follow_up",
      "language": "en",
      "components": [
        { "type": "body", "parameters": [{ "type": "text", "text": "Sara" }] }
      ]
    }
  }
}

The API enforces WhatsApp’s 24-hour window rules. You’ll receive a templateWindowStatus object in the response if the conversation fell outside the interactive window.

Conversation history

GET /conversations/{conversationId}/messages?limit=50&before=2024-12-01T11:00:00Z

Returns the latest messages newest-first. The before cursor lets you paginate backwards without missing messages.

{
  "data": [
    {
      "id": "msg_01JGDP5CQ0",
      "conversationId": "whatsapp:+971500000000",
      "type": "text",
      "direction": "inbound",
      "content": "Hi, can you confirm my order-,
      "createdAt": "2024-12-01T10:59:10.000Z",
      "metadata": {
        "platformMessageId": "wamid.HBgMMjU0",
        "source": "whatsapp_unified_system"
      }
    }
  ],
  "requestId": "req_3cfa",
  "nextBefore": "2024-12-01T10:59:10.000Z"
}

Webhooks

Manage endpoints under Settings -> API & Webhooks or via the API:

  • POST /webhooks - register an endpoint with url, events, and optional secret.
  • GET /webhooks - list subscriptions and delivery stats.
  • DELETE /webhooks/{id} - remove the subscription.

Supported events: message.created, message.updated, conversation.assigned, conversation.resolved, contact.created, contact.updated.

Webhook delivery notes:

  • All requests include X-OnSync-Signature (HMAC-SHA256). Use the provided secret to verify authenticity before processing.
  • Retries use exponential backoff (up to four attempts). Respond with 2xx to acknowledge receipt.
  • You can pause endpoints from the UI if you need to perform maintenance without deleting secrets.

Errors & observability

StatusMeaningTypical fix
400Validation failedCheck Zod-style error details in the response body.
401Invalid or missing API keyRegenerate the key or store it in a secure server-side variable.
403Key lacks permissionEdit the key in the UI to grant write:messages, read:contacts, etc.
409Duplicate detectedUpdate the contact instead of creating a new record.
429Rate limit exceededWait before retrying or request a quota increase.

Every response carries requestId. Send that value to support@onsync.com when you need debugging help.

Security best practices

  • Never expose API keys in client-side code. Proxy calls through a secure backend or serverless function.
  • Use dedicated keys per environment (staging vs. production) so you can revoke one without interrupting the other.
  • Rotate webhook secrets whenever you rotate API keys.
  • Combine OnSync webhooks with your own queue (SQS, Pub/Sub, Redis) if you need guaranteed processing order.

Need an endpoint that isn’t listed here? Reach out and the OnSync platform team can enable beta access or design a new route with you.