This section gives programmatic access to your own CRM leads: a website or an external form can send inquiries straight into the cabinet, and your system can read them and move them through statuses.
Base URL: https://developers.grem.capital/api/v1.
Leads are private. Unlike the public listing catalog, there is no access without the right scope: reading needs leads:read, changes need leads:write. You see only the leads where you are the sender or the recipient. Requests are not charged.
List
GET /leads?status=new&type=buy&priority=hot&page=1&limit=20
Authorization: Bearer gsk_live_...
Filters: status, type, priority, source, role, archived, pool, from, to, page, limit, sort. Archived leads are not in the normal list - add archived=true. pool=true (agency keys only) - the leads in the agency's shared pool; a personal key ignores it.
limit (1-50, default 20) and page (from 1) outside the range are cut into it, not refused. Other invalid values of a known parameter (an unknown enum value, a non-integer page, an invalid date in from or to) are refused with 400 validation naming the field.
One lead
GET /leads/{id}?expand=history,documents
expand adds the status and action history (history) and the attached documents (documents).
Lead shape
id,status,type,priority,source,tags,isArchived;type-buy,rent,viewing,sell,contract,transferorusercreatedAt,updatedAt,lastActivityAtcustomer- name, country, messenger and acontactblock (phone,email,messengerHandle,profileUrl)budget-{ value, currency }intent- city, districts, deal type and the client's intentcomments- the client's comment and your own, separatelyobject- the listing the inquiry is aboutagency- only on agency leads: the agency id and whether the lead sits in the shared pool
Other brokers' contacts, internal scores and service flags are never returned.
Send in an inquiry
curl -X POST https://developers.grem.capital/api/v1/leads \
-H "Authorization: Bearer gsk_live_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: form-2026-09-07-0001" \
-d '{
"customer": {
"name": "Olena Kovalchuk",
"country": "UA",
"contact": { "phone": "+380971234567", "email": "[email protected]" }
},
"type": "buy",
"budget": { "value": 120000, "currency": "USD" },
"intent": { "targetCity": "Kyiv", "leadIntent": "buyer" },
"comments": "Looking for a 2-room flat near the metro",
"priority": "warm",
"consent": true
}'
Required: customer.name and at least one way to reach the client in customer.contact. type - buy (default) or rent. priority - hot, warm or cold. Add objectId if the inquiry is about a specific listing, and up to ten of your own tags.
Idempotency-Key saves you from duplicates: if your form repeats the request after a timeout, the lead is not created twice. See Idempotency.
pool: true sends the inquiry to the shared distribution pool instead of your CRM. By default the lead comes to you.
Every lead created through the API is marked with the «API» source in the cabinet, so you can tell it apart.
Change a lead
PATCH /leads/{id}
{ "status": "in progress", "priority": "hot", "tags": ["mortgage"], "brokerComments": "..." }
You can change the status, priority, tags and your own comment. One field is enough. Statuses: new, in progress, processing, agreement, closed, not target, failed. The cabinet rules apply: a lead with a listing is closed through finalization in the cabinet (code: finalize), a lead waiting for the commission keeps its status (fee_pending), a closed deal under a contract changes only in the cabinet (closed) - 422 with the reason in code. Other reasons: sender (you passed the lead on - its recipient handles it), module (a Swipe Match lead, its status follows the module), agreement, network_readonly, forbidden.
Remove a lead
DELETE /leads/{id}
This archives the lead rather than deleting it: it leaves the normal list but stays available with ?archived=true. A lead with an active contract or a finalization agreement, a closed lead with a listing that is not finalized, and a lead waiting for the commission are not archived: 422 with code contract_active, agreement, finalize or fee_pending.
Listings for a lead
GET /leads/{id}/matches?page=1&limit=20
Returns listings that fit the client's request: type, city and budget come from the lead itself or from the linked listing. Free.
Agency pool
Agency keys have two pool actions:
POST /leads/{id}/claim take a lead from the pool
POST /leads/{id}/claim?assignTo=... assign it to a team member
POST /leads/{id}/return-to-pool return a lead to the pool
- Claim: by default the lead goes to the agency owner;
assignTo(member id) can be passed by the owner or a manager. - Return to pool: a manager and above, or the agent the lead is assigned to. Optional body:
{"reason": "..."}. A lead the pool rules archived -422withcode: pool_archived: restore it in the cabinet first. - A personal key or an insufficient role -
403withtitle: forbidden; claiming a lead that is no longer in the pool -404. - Both actions send a
lead.updatedevent.
Watching for changes
Instead of polling the list, subscribe to lead.created and lead.updated - see Webhooks. The event has no personal data: it only says which lead changed; you read the card with a separate request.
Related
- Listings - the catalog leads refer to.
- Swipe Match - module leads for partner brokers.
- Webhooks - events about new and changed leads.
- Errors - reading refusals.