Sync Protocol
Contract for the REST endpoints your CRM must expose to integrate with Spot2 Ingestion.
Properties Endpoint
Main endpoint that returns active listings explicitly selected by the user to appear in Spot2.
GET /api/v1/spot2/properties?updated_since=2026-07-01T00:00:00Z&offset=0&limit=200 HTTP/1.1
Host: your-crm.com
x-api-key: <your-api-key>
Accept: application/json
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
updated_since | ISO 8601 | Not on first cycle; yes on incremental cycles | Returns listings selected for Spot2 and modified since this date. |
offset | integer | Yes | Offset-based cursor. The first request uses 0. |
limit | integer | Yes | Requested page size. The standard value is 200. |
Behaviour
- On the first cycle we do not send
updated_since; your API must return the full catalog of active listings selected for Spot2. - After a successful cycle, we send
updated_sincewith the timestamp of the last successful cycle. - Your API must return only listings selected for Spot2 with changes after
updated_since. - If a property is still active in your CRM but the user removed it from the Spot2 selection, report it in the deleted endpoint.
- If there are no results, respond with
200plusdata: []andmeta.next: null, or with204 No Content.
Response Format
We recommend returning properties under data and pagination under meta:
{
"data": [
{
"external_id": "PROP-001",
"property_type": "office",
"modality": "rent",
"updated_at": "2026-07-24T15:40:43Z",
"price": {
"currency": "MXN",
"rent_price": 120000,
"sale_price": null
},
"location": {
"latitude": 19.4326,
"longitude": -99.1937,
"street": "Avenida Presidente Masaryk",
"city": "Ciudad de México",
"state": "Ciudad de México",
"postal_code": "11560"
},
"contact": {
"name": "Broker CRM",
"email": "broker@example.com",
"phone": "525512345678"
}
}
],
"meta": {
"next": "/api/v1/spot2/properties?updated_since=2026-07-01T00:00:00Z&offset=200&limit=200",
"total_count": 580
}
}
| Field | Type | Description |
|---|---|---|
data | object[] | List of properties. Each object follows the Property Schema. |
meta.next | string or null | URL or marker for the next page. null or absent when there are no more pages. |
meta.total_count | integer | Optional. Expected total for auditability. |
The standard contract recommends data, but Spot2 also tolerates objects or items as the property array name. Use data for new integrations.
Pagination
Pagination is offset-based:
GET /api/v1/spot2/properties?updated_since=2026-07-01T00:00:00Z&offset=200&limit=200 HTTP/1.1
Host: your-crm.com
x-api-key: <your-api-key>
Spot2 continues while meta.next has a value. The cycle ends when meta.next is null, empty, or absent.
HTTP Status Codes
| Status | Meaning |
|---|---|
200 | Success. Feed received correctly. |
204 | Empty feed. No properties to process on that page or cycle. |
400 | Invalid parameter, for example malformed updated_since. |
401 / 403 | Invalid credential or insufficient permission. |
429 | Temporary rate limit. |
503 | Temporary maintenance. |
Deleted Endpoint
Required endpoint to report properties deleted from the CRM or removed from the Spot2 selection.
GET /api/v1/spot2/properties/deleted?since=2026-07-01T00:00:00Z HTTP/1.1
Host: your-crm.com
x-api-key: <your-api-key>
Accept: application/json
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
since | ISO 8601 | Not on first cycle; yes on incremental cycles | Returns external_ids deleted or removed from Spot2 since this date. |
On the first cycle we do not send since. Your API may return all deleted IDs it retains or an empty set.
Response Format
{
"deleted_ids": ["PROP-001", "PROP-002"],
"since": "2026-07-01T00:00:00Z",
"generated_at": "2026-07-24T15:40:43.143Z"
}
If there are no deletions, respond:
{
"deleted_ids": [],
"since": null,
"generated_at": "2026-07-24T15:40:43.143Z"
}
| Field | Type | Description |
|---|---|---|
deleted_ids | string[] | external_ids of properties deleted or removed from the Spot2 selection. Required, even when empty. |
since | ISO 8601 or null | Echo of the received cursor, or null when not applicable. |
generated_at | ISO 8601 or null | Timestamp when the response was generated. |
You may also respond with 204 No Content; Spot2 interprets it as deleted_ids: [].
Retention
Your CRM must retain deletion history for at least 30 days. If since is older than your retention window, return all deleted IDs you have available.
Authentication
The standard contract recommends API key by header:
x-api-key: <your-api-key>
We can also configure Bearer Token if your platform requires it:
Authorization: Bearer <your-token>
Requirements:
- Dedicated credential for Spot2.
- Read-only scope for properties and deleted items.
- No automatic expiration. If you need to rotate it, coordinate a transition window.
Rate Limits And Timeout
- Recommended limit: at least 60 requests per minute for the Spot2 credential.
- If you need to apply temporary rate limiting or maintenance, respond with a clear HTTP status (
429or503) and a readable JSON message. - Standard operational timeout: up to 300 seconds per request. We recommend that your API respond well before that limit.
What Not To Do
- Do not return the full CRM inventory; return only listings selected for Spot2.
- Do not change item order between paginated requests in the same cycle.
- Do not use infinite pagination without an end marker.
- Do not report deletions by absence in the main feed. Always use
/properties/deleted. - Do not include credentials in query parameters.
Next Reading
- Property Schema: complete field reference.
- Deletion Protocol: retention and flow details.
- Security: authentication, Bearer Token, and TLS.