RaabtaHQ
Submit an inquiry

Submit an inquiry

POST/api/v1/inquiries

scope inquiries:writeIdempotent

Records an inquiry — this is the endpoint to point a website contact form at. At least one of email or phone is required. Send any extra form fields in metadata; they are shown in the inbox and included in the CSV export. If the sender is on the account’s blocklist the inquiry is refused with 422 unprocessable and reason: "sender_blocked". Call it from your own server, not from browser JavaScript: an API key in a public page is readable by anyone who views the source. Send an Idempotency-Key header so a retry after a network blip does not create a second lead.

Body

application/json
NameTypeDescription
namerequired
stringWho sent it
emailoptional
string (email) | null
phoneoptional
string | null
companyoptional
string | null
topicoptional
stringYour own category — free text. Becomes a filter in the inbox.Default: general
messagerequired
stringWhat they wrote
sourceoptional
string | nullWhich form this came from, e.g. "Pricing page"
source_pathoptional
string | nullThe page path the form was on
metadataoptional
map<string, string | number | boolean | null>Any additional form fields, verbatim: flat key/value pairs. Nested objects and arrays are rejected — join a multi-select into a string yourself.
Request
curl -X POST "https://your-crm.example.com/api/v1/inquiries" \
  -H "Authorization: Bearer $RAABTA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2a9e-3b4d-4c5e-8f7a-9b0c1d2e3f4a" \
  -d '{
    "name": "Ayesha Khan",
    "email": "ayesha@example.com",
    "phone": "+971501234567",
    "company": "Khan Trading LLC",
    "topic": "Quote request",
    "message": "Do you cover Jumeirah? Looking for a quote for two units.",
    "source": "Pricing page",
    "source_path": "/pricing",
    "metadata": {
      "Budget": "AED 10,000–25,000",
      "Preferred contact": "WhatsApp",
      "Units": 2
    }
  }'
Response · 201 Created
{
  "data": {
    "id": "a3f1c2d4-5e6b-4f78-9a0b-1c2d3e4f5a6b",
    "status": "new",
    "topic": "Quote request",
    "name": "Ayesha Khan",
    "email": "ayesha@example.com",
    "phone": "+971501234567",
    "company": "Khan Trading LLC",
    "message": "Do you cover Jumeirah? Looking for a quote for two units.",
    "source": "Pricing page",
    "source_path": "/pricing",
    "metadata": {
      "Budget": "AED 10,000–25,000",
      "Preferred contact": "WhatsApp",
      "Units": 2
    },
    "first_touched_at": null,
    "created_at": "2026-09-02T10:05:00.000Z",
    "updated_at": "2026-09-02T10:05:00.000Z"
  }
}

Response

Wrapped in { data: … }
NameTypeDescription
idrequired
string (uuid)UUID
statusrequired
string (enum)Where the inquiry sits in triagenewin_progressclosedspam
topicrequired
stringYour own category for the inquiry — free text, e.g. "Billing"
namerequired
stringWho sent it
emailrequired
string | nullSender email, lowercased; null if the form collected only a phone
phonerequired
string | nullSender phone; null if the form collected only an email
companyrequired
string | nullSender company, when the form asks
messagerequired
stringWhat they wrote
sourcerequired
string | nullWhich form this came from, e.g. "Pricing page"
source_pathrequired
string | nullThe page path the form was on
metadatarequired
map<string, string | number | boolean | null>Any additional form fields, verbatim — flat key/value pairs. Shown in the inbox and included in the CSV export.
first_touched_atrequired
string (date-time) | nullWhen someone first acted on it; null while untouched
created_atrequired
string (date-time)ISO 8601 timestamp
updated_atrequired
string (date-time)ISO 8601 timestamp

Errors

StatusCodeWhen
400bad_requestThe request could not be parsed: malformed JSON, an invalid cursor, or a query parameter of the wrong shape.
400validation_errorThe body or query failed validation. `details` lists each failing field with a `path` and a `message`.
401unauthorizedNo usable API key: the Authorization header is missing or malformed, or the key is unknown, revoked or expired. The three are deliberately indistinguishable.
403forbiddenThe key is valid but lacks the scope this endpoint requires, or the request came from an address outside the key’s IP allowlist. The message says which.
403account_suspendedThe account this key belongs to is suspended. Rotating the key will not help; contact support.
409conflictThe request conflicts with current state: a duplicate phone number on create, an invalid state transition, or an idempotent request that is still in flight.
422unprocessableThe request was well-formed but cannot be carried out. `reason` is a stable string saying why (for example `outside_window` or `stage_not_in_pipeline`).
429rate_limitedThe per-key budget, or the per-IP budget for failed authentication, is exhausted. Honour `Retry-After` before retrying.
500internalSomething failed on our side. Safe to retry with the same Idempotency-Key; quote `request_id` if it persists.