Create or update a contact

ProRead & write key

Available on the Pro and Enterprise plans (beta).

POST…/public/contacts/upsert

Updates the contact that the business’s identity keys match (mobile, then email, by default), or creates a new one. Answers 200 with contact, the record, and created, which says which happened.

Request
curl https://app.reshta.ir/api/v1/public/contacts/upsert \​  -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}]}'​

Headers

AuthorizationstringrequiredBearer followed by the business API key (rk_live_…).
Idempotency-KeystringrequiredA unique ID for this operation, such as a fresh UUID; retrying with the same key does nothing twice.
Content-Typeapplication/jsonrequiredThe body is UTF-8 JSON.

Body parameters

first_namestring | nulloptionalFirst name.
last_namestring | nulloptionalLast name.
company_iduuid | nulloptionalThe company this record belongs to.
job_titlestring | nulloptionalJob title.
national_idstring | nulloptionalNational ID.
owner_iduuidoptionalThe responsible teammate.
lifecycle_stagestringoptionaldefault: "lead"Lifecycle stage.
birthdaystring | nulloptionalBirthday, YYYY-MM-DD (Gregorian).
unsubscribed_emailbooleanoptionaldefault: falseUnsubscribed from marketing email.
unsubscribed_smsbooleanoptionaldefault: falseUnsubscribed from marketing SMS.
customobjectoptionaldefault: {}Custom fields, keyed by field key.
emailsobject[]optionaldefault: []Email addresses; up to 20.
emails[].emailemailrequiredThe email address.
emails[].labelstring | nulloptionalAn optional label, such as “work”.
emails[].is_primarybooleanoptionaldefault: falseMarks the primary one.
phonesobject[]optionaldefault: []Phone numbers; up to 20.
phones[].phonestringrequiredThe phone or mobile number.
phones[].labelstring | nulloptionalAn optional label, such as “work”.
phones[].is_primarybooleanoptionaldefault: falseMarks the primary one.

Responses and errors

200—Done; the body is the record.
400validation_errorInvalid body, or no Idempotency-Key; details names the field.
401unauthorizedThe key is missing, wrong or revoked, or its creator is no longer active.
403forbiddenThe key has no write access.
409conflictThis Idempotency-Key came with another body, or is still in progress.
429rate_limitedOver 120 requests per minute; Retry-After says how many seconds to wait.
Response
{​  "created": false,​  "contact": {​    "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"​  }​}​

Create an API key and send your first request

Keys are created in the Reshta app and shown once. The API and webhooks (beta) are on the Pro and Enterprise plans, and only a business admin can create a key.

  1. 1Sign in at app.reshta.ir
  2. 2Connection → Developer
  3. 3Create API key