Create or update a contact
ProRead & write keyAvailable on the Pro and Enterprise plans (beta).
POSThttps://app.reshta.ir/api/v1/public…/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" }}