Connect your software to Polisync
Included in the Enterprise plan
API keys and webhooks are available to workspaces on the Enterprise plan. These docs are open to everyone. See pricing or write to hello@polisync.in.
Quick start
The base URL is https://app.polisync.in/api/public/v1. Everything is JSON over HTTPS.
1. Create a key. In Polisync, open Settings, Developers and choose Create API key. Give it only the permissions the integration needs. The key is shown once, so copy it into your server's secret store.
2. Check the connection.
curl -X GET "https://app.polisync.in/api/public/v1/me" \
-H "Authorization: Bearer $POLISYNC_API_KEY"3. Add a customer. You confirm their DPDP consent with consentGiven. Sending an Idempotency-Key makes the request safe to retry.
curl -X POST "https://app.polisync.in/api/public/v1/customers" \
-H "Authorization: Bearer $POLISYNC_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: unique-request-id-123" \
-d '{
"name": "Ramesh Patel",
"type": "individual",
"phone": "+919876543210",
"email": "ramesh.patel@gmail.com",
"dateOfBirth": "1985-03-14",
"city": "Surat",
"state": "Gujarat",
"agencyId": "cmv1a2b3c0002xyzagency",
"consentGiven": true
}'4. Read them back. For example, active policies expiring before the end of the year:
curl -X GET "https://app.polisync.in/api/public/v1/policies?status=active&expiryTo=2026-12-31" \
-H "Authorization: Bearer $POLISYNC_API_KEY"Next, see the API reference, or set up webhooks to be told about changes instead of polling.
Authentication
Send your key in the Authorization header on every request:
Authorization: Bearer psk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxA key belongs to one workspace, so every request only ever sees that workspace's data. Each key carries scopes: the permissions you tick when you create it. A request outside its scopes gets 403 forbidden. A key can never have more power than the person who created it.
| Scope | Allows |
|---|---|
customer:read | List and fetch customers. |
customer:pan | Customers are returned with PAN masked unless this is on. Needs Read customers. |
customer:create | Add customers. You confirm their DPDP consent. |
customer:update | Edit existing customers. |
policy:read | List and fetch policies. |
policy:create | Add policies. Renewals are created automatically. |
policy:update | Edit policies, including status and expiry. |
claim:read | List and fetch claims and their timeline. |
claim:create | Report claims against policies. |
claim:update | Change status, dates and amounts, and add notes. |
renewal:read | List renewals and their status. |
agency:read | List and fetch agencies. |
Keep keys on your server
Anyone holding a key can use it. Never put one in a website, a mobile app or a public repository. Browser calls are not allowed (the API sends no CORS headers). Give each integration its own key, set an expiry, and revoke a key the moment you doubt it. Revoking works on the very next request.
Requests and responses
- Send and receive JSON. Use
Content-Type: application/jsonon writes. Request bodies are limited to 1 MB. - Unknown fields in a request body are rejected, so a typo never silently does nothing.
- Dates are
YYYY-MM-DD. Timestamps are ISO 8601 in UTC. Money is a number in rupees. Phone numbers are Indian mobile numbers in+91format. - Enum values keep their stored form, such as
half_yearlyandnon_corporate. - On
PATCH, send only the fields to change. Sendnullto clear an optional field. - Every response carries an
X-Request-Id. Quote it if you contact support.
A successful response always looks like this:
{
"success": true,
"data": {
"id": "cmv1a2b3c0001xyzcustomer",
"...": "..."
}
}{
"success": true,
"data": [
{
"id": "..."
}
],
"pagination": {
"total": 134,
"page": 1,
"limit": 20,
"totalPages": 7
}
}Pagination, filtering and sync
Lists take page (from 1) and limit (1 to 100, default 20), and return a pagination block. Results are in a stable order, so paging does not repeat or skip records. Each list documents its own filters in the reference.
To keep another system in step, store the time of your last sync and ask for what changed since: ?updatedSince=2026-10-26T00:00:00Z. Every list supports it. Or use webhooks and skip polling.
Rate limits
Each key may make 60 requests a minute. Every response shows where you stand:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in this minute. |
X-RateLimit-Reset | Unix time when the window resets. |
Retry-After | On a 429 only: seconds to wait before trying again. |
When you get 429, wait for Retry-After and retry. For bulk work, slow down and use limit=100. Repeated failed authentication from one address is also throttled.
Errors
Every failure has the same shape, and a stable machine code:
{
"success": false,
"error": "One or more fields are invalid.",
"code": "validation_error",
"details": [
{
"field": "phone",
"message": "Invalid Indian mobile number"
}
]
}Match on code, not on the message text, which may be reworded. details names each field that failed.
| HTTP | code | Meaning |
|---|---|---|
| 400 | invalid_json | The request body is not valid JSON. |
| 401 | unauthorized | The API key is missing, invalid, expired or revoked. |
| 403 | forbidden | The key does not have the scope this endpoint needs. |
| 403 | plan_required | The workspace's plan does not include API access (Enterprise). |
| 403 | account_suspended | The workspace is suspended. |
| 404 | not_found | The record does not exist in your workspace. |
| 409 | conflict | The request clashes with existing data, such as a duplicate policy number. |
| 409 | idempotency_conflict | That Idempotency-Key was already used with a different request. |
| 409 | idempotency_in_progress | A request with that Idempotency-Key is still running. Retry shortly. |
| 413 | payload_too_large | The request body is over 1 MB. |
| 422 | validation_error | A field is missing or invalid. The details array names each one. |
| 403 | plan_limit_reached | Your plan's limit for customers or policies is full. |
| 429 | rate_limited | Too many requests. Wait for the number of seconds in the Retry-After header. |
| 500 | server_error | Something went wrong on our side. Retry; if it persists, contact support. |
Retry 429 and 5xx responses with a growing delay. Do not retry 4xx responses unchanged: fix the request first.
Idempotency
A network failure can leave you not knowing whether a create worked. Send an Idempotency-Key header (a unique value you choose, up to 255 characters) on POST requests. Polisync stores the first successful response for 24 hours:
- The same key with the same request returns the original response again, with
Idempotent-Replayed: true, and creates nothing new. - The same key with a different request returns
409 idempotency_conflict. - A request that failed is not stored, so you can correct it and resend with the same key.
curl -X POST "https://app.polisync.in/api/public/v1/customers" \
-H "Authorization: Bearer $POLISYNC_API_KEY" \
-H "Idempotency-Key: enquiry-form-8421" \
-H "Content-Type: application/json" \
-d '{ ... }'Data protection
Customer records are personal data, and claims and policies can include health information. You are responsible for it under India's DPDP Act 2023, and Polisync is built to help:
- Creating a customer needs
consentGiven: true, and the consent is logged with the key and the caller's IP address. - PAN numbers are masked (
ABCDE****F) unless the key has the explicit full-PAN scope, and always in webhooks. - Send data only to systems you control, over HTTPS, and keep only what you need.
- Delete a customer in Polisync and webhook subscribers are told, so mirrors can remove their copy too.
Read our Privacy Policy and Terms of Service.
Versioning
The version is in the URL (/api/public/v1). Within v1 we only add things: new endpoints, new optional fields, new response fields and new webhook event types. So write your code to ignore fields it does not know. A change that could break your code would ship as v2, with notice and an overlap period. See the changelog.
A machine-readable description is at /developers/openapi.json (OpenAPI 3.1). Import it into Postman, Insomnia or a code generator.