Reshta API docs
Connect your own site, ERP or accounting software to Reshta: create contacts and deals, record orders, and hear about every change through webhooks. REST and JSON, with one key.
- 1Create an API key in ReshtaConnection → Developer
- 2Your first requestYour system to Reshta
curl -H "Authorization: Bearer …" …/contacts - 3Receive a webhookReshta to your systemPOST deal.won
What can you build?
Base URL
Every request goes to this address over HTTPS. Bodies are UTF-8 JSON, times are ISO 8601 in UTC, and amounts are integers in rials.
https://app.reshta.ir/api/v1/publicAuthentication
Every request carries the business API key in the Authorization header. A business admin creates the key in the Reshta app:
- 1Sign in at app.reshta.ir with an admin account; its email must be verified.
- 2Open Connection in the side menu, then Developer.
- 3Create API key: give it a name and choose the access: Read, or Read & write.
- 4Copy the key right away and keep it somewhere safe (a server environment variable).
Authorization: Bearer rk_live_…- A key acts as the teammate who created it; if the key is revoked or that account is deactivated, requests return 401.
- A Read key gets 403 on write requests.
- Never put a key in browser or mobile-app code; call the API only from your own server.
Rate limits
Idempotency
Every write request (POST and PATCH) must send an Idempotency-Key header: a fresh ID per operation, such as a UUID, up to 255 characters. If the same request arrives again, for example after a network drop, Reshta returns the first response and creates nothing twice.
POST /ordersAuthorization: Bearer rk_live_…Idempotency-Key: 7f3c2b1e-4a5d-4c6f-9e1a-2b3c4d5e6f70Content-Type: application/jsonErrors
Every error has the same shape: a stable code your program can branch on, a message for humans, and details; for validation errors, details names the field.
{ "error": { "code": "validation_error", "message": "Invalid request", "details": [ { "field": "emails.0.email", "message": "Invalid email address" } ] }}Pagination
Lists are paginated with a cursor, not page numbers. Each response has data and next_cursor; send next_cursor in the next request. When next_cursor is null you have reached the end. The default page size is 50, at most 100.
GET /contacts?limit=50&cursor=eyJpZCI6IjAxOTJjNGU4In0{ "data": [ … ], "next_cursor": "eyJpZCI6IjAxOTJjNGY5In0"}Versioning
Quickstart
- 1Create a Read & write key
- 2Put it in RESHTA_API_KEY
- 3Create your first contact
curl https://app.reshta.ir/api/v1/public/contacts \ -X POST \ -H "Authorization: Bearer $RESHTA_API_KEY" \ -H "Idempotency-Key: 7f3c2b1e-4a5d-4c6f-9e1a-2b3c4d5e6f70" \ -H "Content-Type: application/json" \ -d '{"first_name":"سارا","last_name":"رضایی","phones":[{"phone":"09121234567","is_primary":true}]}'{ "id": "0192c4e8-7b1a-7c3e-9f20-5d6a1b2c3d4e", "first_name": "سارا", "last_name": "رضایی", "company_id": null, "company_name": null, "job_title": null, "national_id": null, "owner_id": "0192a7f0-3b4c-7d5e-8f60-718293a4b5c6", "lifecycle_stage": "lead", "birthday": null, "unsubscribed_email": false, "unsubscribed_sms": false, "is_sample": false, "source": null, "marketing_block_reason": null, "address": null, "custom": {}, "emails": [], "phones": [ { "id": "0192c4e8-7b1b-7a10-8c21-3d4e5f607182", "phone": "09121234567", "label": null, "is_primary": true } ], "created_at": "2026-10-26T14:05:12.000Z", "updated_at": "2026-10-26T14:05:12.000Z"}