Download OpenAPI specification:
REST API for estate agent partners to submit referrals, track property progress, access documents, and receive real-time webhook notifications.
Your Bid account manager will provide a client_id and client_secret. See the
Quickstart guide to make your first API call in 5 minutes.
Your Bid account manager will provide:
client_id — UUID identifying your integrationclient_secret — starts with bid_cs_ (store securely, never expose in client-side code)curl -X POST https://api.thebid.uk/v1/oauth/token \
-H "Content-Type: application/json" \
-d '{
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"grant_type": "client_credentials"
}'
Response (RFC 6749 §5.1 — flat JSON, no data wrapper):
{
"access_token": "bid_at_...",
"token_type": "Bearer",
"expires_in": 3600,
"permissions": ["referrals:read", "referrals:write", "properties:read", "buyers:read"]
}
curl https://api.thebid.uk/v1/me \
-H "Authorization: Bearer bid_at_..."
Response:
{
"data": {
"agent_id": "uuid",
"agent_name": "Acme Estate Agents",
"branches": [
{ "branch_id": "uuid", "branch_name": "London Office", "phone_number": "020 7123 4567" }
],
"api_key_name": "Production Key",
"permissions": ["referrals:read", "referrals:write", "properties:read", "buyers:read"]
},
"request_id": "uuid"
}
Fetch enum values so your UI stays in sync with accepted values:
curl https://api.thebid.uk/v1/enums
Response includes referral_types, property_types, tenure_types, bedroom_options, property_status_categories, offer_statuses, document_types, webhook_event_types, and more. No auth required.
curl https://api.thebid.uk/v1/branches \
-H "Authorization: Bearer bid_at_..."
Response:
{
"data": [
{ "branch_id": "uuid", "branch_name": "London Office", "phone_number": "020 7123 4567" }
],
"request_id": "uuid"
}
Cache the branch_id values — you'll need one to submit referrals.
curl -X POST https://api.thebid.uk/v1/referrals \
-H "Authorization: Bearer bid_at_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"branch_id": "YOUR_BRANCH_ID",
"type": "new_instruction",
"property": {
"house_name_or_number": "42",
"street_name": "High Street",
"town_or_city": "London",
"post_code": "SW1A 1AA",
"property_type": "terraced",
"number_of_bedrooms": "3",
"number_of_bathrooms": "2",
"tenure": "freehold",
"vacant": true
},
"customers": [{
"name": "Jane Smith",
"email": "jane@example.com",
"phone": "07700 900000",
"house_name_or_number": "10",
"street_name": "Oak Road",
"town_or_city": "London",
"post_code": "SW1A 2BB"
}],
"notes": "Seller wants a quick sale"
}'
Response (201):
{
"data": {
"referral_id": "uuid",
"status": "new",
"created_at": "2026-05-23T14:00:00Z"
},
"request_id": "uuid"
}
Once a referral is instructed and a property is created, you can track buyers and offers:
# Get property details (includes milestones)
curl "https://api.thebid.uk/v1/properties?property_id=PROPERTY_UUID" \
-H "Authorization: Bearer bid_at_..."
# Get buyers for a property
curl "https://api.thebid.uk/v1/buyers?property_id=PROPERTY_UUID" \
-H "Authorization: Bearer bid_at_..."
# Get a single buyer with full offer history
curl "https://api.thebid.uk/v1/buyers?buyer_id=BUYER_UUID" \
-H "Authorization: Bearer bid_at_..."
Receive real-time notifications instead of polling:
curl -X POST https://api.thebid.uk/v1/webhooks \
-H "Authorization: Bearer bid_at_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhooks/bid",
"events": ["referral.status_changed", "property.status_changed", "buyer.offer_updated"]
}'
Store the returned secret immediately — it's shown once and used to verify payload signatures.
The Bid API uses OAuth 2.0 Client Credentials for machine-to-machine authentication.
client_id and client_secret from BidcURL:
curl -X POST https://api.thebid.uk/v1/oauth/token \
-H "Content-Type: application/json" \
-d '{
"client_id": "your-uuid",
"client_secret": "bid_cs_your_secret",
"grant_type": "client_credentials"
}'
Node/TypeScript:
const res = await fetch("https://api.thebid.uk/v1/oauth/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: process.env.BID_CLIENT_ID,
client_secret: process.env.BID_CLIENT_SECRET,
grant_type: "client_credentials",
}),
});
const token = await res.json();
// token.access_token, token.expires_in
C#:
var client = new HttpClient();
var response = await client.PostAsync(
"https://api.thebid.uk/v1/oauth/token",
new StringContent(JsonSerializer.Serialize(new {
client_id = Environment.GetEnvironmentVariable("BID_CLIENT_ID"),
client_secret = Environment.GetEnvironmentVariable("BID_CLIENT_SECRET"),
grant_type = "client_credentials"
}), Encoding.UTF8, "application/json"));
var result = await response.Content.ReadFromJsonAsync<TokenResponse>();
Tokens expire after 3600 seconds (1 hour). On receiving a 401 response, re-authenticate:
async function apiCall(url: string, options: RequestInit = {}) {
let token = await getToken(); // cached token
let res = await fetch(url, {
...options,
headers: { ...options.headers, Authorization: `Bearer ${token}` },
});
if (res.status === 401) {
token = await refreshToken(); // exchange credentials again
res = await fetch(url, {
...options,
headers: { ...options.headers, Authorization: `Bearer ${token}` },
});
}
return res;
}
client_secret to source controlclient_secret starts with bid_cs_ — if you see this in logs, rotate immediately429 Too Many Requests: back off and retry after the rate window resets (1 minute)Your client is issued with specific permissions. Calling an endpoint you don't have permission for returns 403 FORBIDDEN:
| Permission | Endpoints |
|---|---|
referrals:read |
GET /v1/referrals |
referrals:write |
POST /v1/referrals |
properties:read |
GET /v1/properties |
buyers:read |
GET /v1/buyers |
documents:read |
POST /v1/documents/{id}/access-url |
webhooks:manage |
GET/POST/DELETE /v1/webhooks |
The following endpoints require a valid token but no specific permission:
GET /v1/me — your account infoGET /v1/branches — your branch listThe following endpoints require no authentication:
GET /v1/health — API health checkGET /v1/enums — reference data / enum valuesAttribute marketplace buyers to your own campaigns, channels, or internal
IDs using the optional external_ref reference on every buyer.
Append ?external_ref=YOUR_REF to any marketplace or branded microsite
URL. A property URL works best, because the reference is attributed to that
specific property:
https://marketplace.thebid.uk/{slug}/property/{id}?external_ref=YOUR_REF
YOUR_REF is any free-text value you control (for example a campaign code
or your own internal customer ID). It is treated as opaque text, trimmed,
and capped at 128 characters.
Buyer record is stamped with your reference.The external_ref is returned on every buyer response, and you can list
all buyers carrying a reference:
curl https://api.thebid.uk/v1/buyers?external_ref=YOUR_REF \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Lookups are scoped to your own agent — you only ever see your own buyers, even if another partner happens to use the same reference value.
You can also set external_ref directly when creating a referral via the
API; see the Referrals endpoint.
Receive real-time notifications when referral status changes, properties reach milestones, or new buyers are registered.
curl -X POST https://api.thebid.uk/v1/webhooks \
-H "Authorization: Bearer bid_at_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhooks/bid",
"events": ["referral.created", "referral.status_changed", "property.status_changed"]
}'
Requirements:
https://localhost, private IPs (10.*, 172.16-31.*, 192.168.*), or .local domainssecret is returned once on creation — store it immediately| Event | Trigger |
|---|---|
referral.created |
New referral submitted |
referral.status_changed |
Referral status updated |
property.status_changed |
Property status category changes |
property.milestone_completed |
A milestone is marked complete |
property.document_added |
A document is added to a property |
property.marketplace_updated |
A property's marketplace listing is published/unpublished or its sale status changes |
buyer.created |
New buyer registered on a property |
buyer.offer_updated |
Buyer's offer status changes |
Every delivery uses this structure:
{
"version": "1",
"event_id": "uuid",
"event_type": "referral.status_changed",
"created_at": "2026-05-23T14:30:00Z",
"data": {
"referral_id": "uuid",
"old_status": "new",
"new_status": "in_progress"
}
}
Branch on version for forward compatibility. Treat missing version as "1".
No PII in payloads — only IDs and status values. Fetch full details via the GET endpoints.
Every delivery includes three headers:
X-Bid-Event — the event typeX-Bid-Timestamp — Unix epoch seconds at delivery timeX-Bid-Signature — sha256=<hex HMAC>The signed string is: timestamp + "." + raw_body
Node/TypeScript:
import crypto from "crypto";
function verifyWebhook(body: string, headers: Headers, secret: string): boolean {
const timestamp = headers.get("x-bid-timestamp")!;
const signature = headers.get("x-bid-signature")!;
// Reject stale deliveries (replay protection)
if (Math.abs(Date.now() / 1000 - parseInt(timestamp)) > 300) {
return false;
}
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${body}`)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected),
);
}
C#:
bool VerifyWebhook(string body, string timestamp, string signature, string secret) {
if (Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - long.Parse(timestamp)) > 300)
return false;
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes($"{timestamp}.{body}"));
var expected = "sha256=" + BitConverter.ToString(hash).Replace("-", "").ToLower();
return CryptographicOperations.FixedTimeEquals(
Encoding.UTF8.GetBytes(signature),
Encoding.UTF8.GetBytes(expected));
}
Failed deliveries (non-2xx or timeout) are retried with exponential backoff:
| Attempt | Retry after |
|---|---|
| 1 | 30 seconds |
| 2 | 2 minutes |
| 3 | 15 minutes |
| 4 | 1 hour |
| 5 | 4 hours |
After 5 failed attempts, the event is marked as dead-letter (no further retries).
[Bid Webhook] → [Your HTTPS endpoint] → [Message Queue] → [Worker]
Accept the delivery immediately (return 200), queue it for processing. This avoids timeouts if your processing is slow.
Access property documents (legal packs, AML reports, etc.) via short-lived signed URLs.
Documents are included in property responses when you pass ?include=documents:
curl "https://api.thebid.uk/v1/properties?property_id=UUID&include=documents" \
-H "Authorization: Bearer bid_at_..."
Response includes:
{
"data": {
"property_id": "...",
"documents": [
{
"id": "document-uuid",
"name": "1716480000-abc123-legal-pack.pdf",
"type": "Legal Pack",
"uploaded_at": "2026-05-23T10:00:00Z",
"modified_at": "2026-05-23T10:00:00Z"
}
]
}
}
Notes:
name is the verbatim last path segment from storage — do not assume a stable formatfile_size and mime_type are intentionally not included (not stored on the document record)properties:read and documents:read permissionscurl -X POST "https://api.thebid.uk/v1/documents/DOCUMENT_ID/access-url" \
-H "Authorization: Bearer bid_at_..."
Response:
{
"data": {
"url": "https://storage.example.com/sign/documents/...",
"expires_in": 120
}
}
The signed URL expires after 120 seconds. Download immediately:
const { data } = await bidApi.post(`/v1/documents/${docId}/access-url`);
const fileResponse = await fetch(data.url);
const buffer = await fileResponse.arrayBuffer();
fs.writeFileSync(`downloads/${filename}`, Buffer.from(buffer));
All errors return a JSON envelope with an error object containing code, message, and optionally details.
| HTTP | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR |
Request body failed validation or missing required header |
| 401 | UNAUTHORIZED |
Missing, invalid, or expired token |
| 403 | FORBIDDEN |
Token lacks required permission |
| 404 | NOT_FOUND |
Resource not found (or cross-agent access) |
| 405 | METHOD_NOT_ALLOWED |
HTTP method not supported on this endpoint |
| 409 | CONFLICT |
Duplicate referral detected |
| 429 | RATE_LIMITED |
Too many requests — wait and retry |
| 500 | INTERNAL_ERROR |
Server error (message is always "Internal server error") |
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Missing required field: branch_id",
"details": ["Missing required field: branch_id", "Missing required field: post_code"],
"request_id": "uuid"
}
}
details is only present on 4xx errors"Internal server error"When submitting a referral that matches an existing address:
Open referral exists:
{
"error": {
"code": "CONFLICT",
"message": "An open referral already exists for this address",
"details": {
"reason": "open_referral",
"referral_id": "existing-uuid",
"status": "in_progress"
}
}
}
Active property at address:
{
"error": {
"code": "CONFLICT",
"message": "An active property exists for this address",
"details": {
"reason": "active_property",
"property_id": "property-uuid",
"referral_id": "referral-uuid",
"status_category": "for_sale"
}
}
}
POST /referrals requires an Idempotency-Key header (max 255 characters, UUID recommended):
curl -X POST .../v1/referrals \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
...
POST /referrals = 400 VALIDATION_ERROR/webhooks, /documents) do not require idempotency keysconst res = await fetch(url, options);
if (res.status === 401) {
// Re-authenticate and retry
token = await getNewToken();
return retry(url, options, token);
}
if (res.status === 429) {
// Back off 60 seconds (rate window)
await sleep(60_000);
return retry(url, options, token);
}
if (res.status === 409) {
const { error } = await res.json();
// Use error.details.reason to decide: link to existing or alert user
}
if (res.status >= 500) {
// Retry with exponential backoff (Bid is having issues)
}
Returns the authenticated agent's details, branches, API key name, and permissions. Use this to verify your credentials and discover branch IDs.
{- "data": {
- "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
- "agent_name": "Acme Estate Agents",
- "branches": [
- {
- "branch_id": "7a4e8e99-89f2-4a0f-b66c-fc595dda2dbc",
- "branch_name": "London Office",
- "phone_number": "020 7123 4567"
}
], - "api_key_name": "Production Key",
- "permissions": [
- "referrals:read",
- "referrals:write",
- "properties:read",
- "buyers:read"
]
}, - "request_id": "266ea41d-adf5-480b-af50-15b940c2b846"
}Returns all branches for the authenticated agent. Use the branch_id
values when creating referrals. No specific permission required — any
valid token works.
{- "data": [
- {
- "branch_id": "7a4e8e99-89f2-4a0f-b66c-fc595dda2dbc",
- "branch_name": "London Office",
- "phone_number": "020 7123 4567"
}
], - "request_id": "266ea41d-adf5-480b-af50-15b940c2b846"
}OAuth 2.0 Client Credentials grant (RFC 6749 §4.4).
Client credentials can be provided via:
Authorization: Basic base64(client_id:client_secret)client_id and client_secret in JSON or form-urlencoded bodyDo not use both methods simultaneously.
| grant_type required | string Value: "client_credentials" |
| client_id | string <uuid> Required unless using HTTP Basic auth |
| client_secret | string Required unless using HTTP Basic auth |
{- "access_token": "bid_at_a1b2c3d4e5f6...",
- "token_type": "Bearer",
- "expires_in": 3600,
- "permissions": [
- "referrals:read",
- "referrals:write",
- "properties:read"
]
}Returns referrals for the authenticated agent with pagination.
| page | integer Default: 1 |
| per_page | integer <= 200 Default: 50 |
| referral_id | string <uuid> Return a single referral by ID |
| status | string |
| branch_id | string <uuid> |
| created_after | string <date-time> |
| external_ref | string Filter by exact external reference match. |
{- "data": {
- "referral_id": "2d946960-d63d-4137-b67f-4dc8d4a3067c",
- "created_at": "2019-08-24T14:15:22Z",
- "status": "new",
- "branch_id": "7a4e8e99-89f2-4a0f-b66c-fc595dda2dbc",
- "type": "new_instruction",
- "property": {
- "house_name_or_number": "string",
- "street_name": "string",
- "flat_number": "string",
- "locality": "string",
- "town_or_city": "string",
- "post_code": "string",
- "property_type": "detached",
- "number_of_bedrooms": "string",
- "number_of_bathrooms": "string",
- "tenure": "freehold",
- "vacant": true,
- "lease_length": 0,
- "service_charge_ground_rent": 0
}, - "customers": [
- {
- "name": "string",
- "email": "string",
- "phone": "string",
- "address": {
- "house_name_or_number": "string",
- "street_name": "string",
- "flat_number": "string",
- "locality": "string",
- "town_or_city": "string",
- "post_code": "string"
}, - "moving_abroad": "yes"
}
], - "notes": "string",
- "valuation_notes": "string",
- "external_ref": "string",
- "referral_agent_email": "string"
}, - "pagination": {
- "page": 0,
- "per_page": 0,
- "total": 0
}, - "request_id": "string"
}Submit a new property referral. Requires the Idempotency-Key header.
Returns 409 CONFLICT if a duplicate address is found.
The request body must contain property (object) and customers (array of 1–5 entries).
| Idempotency-Key required | string <= 255 characters Unique key to prevent duplicate submissions (UUID recommended) |
| branch_id required | string <uuid> |
| type required | string Enum: "new_instruction" "on_the_market_with_you_already" "sale_fallen_through" "valuation" |
required | object |
required | Array of objects [ 1 .. 5 ] items Array of customers (1-5 entries). Each entry requires name, phone, email, and address fields. |
| notes | string |
| valuation_notes | string |
| external_ref | string Optional external reference string (e.g. your own internal ID). |
| referral_agent_email | string Optional referral agent email. Captured and stored for future use. |
{- "branch_id": "7a4e8e99-89f2-4a0f-b66c-fc595dda2dbc",
- "type": "new_instruction",
- "property": {
- "house_name_or_number": "string",
- "street_name": "string",
- "town_or_city": "string",
- "post_code": "string",
- "flat_number": "string",
- "locality": "string",
- "property_type": "detached",
- "number_of_bedrooms": "string",
- "number_of_bathrooms": "string",
- "tenure": "freehold",
- "vacant": true,
- "lease_length": 0,
- "service_charge_ground_rent": 0
}, - "customers": [
- {
- "name": "string",
- "email": "user@example.com",
- "phone": "string",
- "house_name_or_number": "string",
- "street_name": "string",
- "flat_number": "string",
- "locality": "string",
- "town_or_city": "string",
- "post_code": "string",
- "moving_abroad": "yes"
}
], - "notes": "string",
- "valuation_notes": "string",
- "external_ref": "string",
- "referral_agent_email": "string"
}{- "data": {
- "referral_id": "2d946960-d63d-4137-b67f-4dc8d4a3067c",
- "status": "new",
- "created_at": "2019-08-24T14:15:22Z"
}, - "request_id": "string"
}| page | integer Default: 1 |
| per_page | integer <= 200 Default: 50 |
| property_id | string <uuid> |
| status_category | string |
| branch_id | string <uuid> |
| external_ref | string Filter by exact external reference match. |
| include | string Example: include=documents Comma-separated includes. Supports "documents" (requires documents:read permission). |
{- "data": {
- "property_id": "05003a8a-8f3c-454b-8884-a906ec46f5f5",
- "created_at": "2019-08-24T14:15:22Z",
- "referral_id": "2d946960-d63d-4137-b67f-4dc8d4a3067c",
- "branch_id": "7a4e8e99-89f2-4a0f-b66c-fc595dda2dbc",
- "status_category": "for_sale",
- "sale_type": "auction",
- "property": {
- "house_name_or_number": "string",
- "street_name": "string",
- "flat_number": "string",
- "locality": "string",
- "town_or_city": "string",
- "post_code": "string",
- "property_type": "string",
- "number_of_bedrooms": "string",
- "tenure": "string",
- "vacant": true
}, - "customers": [
- {
- "name": "string",
- "email": "string",
- "phone": "string",
- "address": {
- "house_name_or_number": "string",
- "street_name": "string",
- "flat_number": "string",
- "locality": "string",
- "town_or_city": "string",
- "post_code": "string"
}, - "moving_abroad": "yes"
}
], - "external_ref": "string",
- "milestones": [
- {
- "milestone": "string",
- "completed_at": "2019-08-24T14:15:22Z",
- "is_skipped": true
}
], - "documents": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "type": "seller_agreement",
- "uploaded_at": "2019-08-24T14:15:22Z",
- "modified_at": "2019-08-24T14:15:22Z"
}
]
}, - "pagination": {
- "page": 0,
- "per_page": 0,
- "total": 0
}, - "request_id": "string"
}Buyer and offer data endpoints, including the optional external_ref tracking reference (see the Buyer Tracking guide)
Three modes (provide exactly one parameter):
?property_id=UUID — all buyers for a property (with latest offer for each)?buyer_id=UUID — single buyer with full offer history, address, company, and co-buyers?external_ref=STRING — all buyers carrying that external reference (with latest offer for each)In list modes (property_id or external_ref) you can additionally pass
?offer_status= to return only buyers whose latest offer has that status.
Not applicable to buyer_id (single-buyer) mode.
A buyer may be purchasing through a company and alongside additional
buyers (co-buyers). List modes include the company and a
co_buyer_count; the single-buyer mode additionally returns the full
co_buyers array.
Agent-scoped: only returns buyers for properties belonging to your agent.
Requires buyers:read permission.
| property_id | string <uuid> List all buyers for this property |
| buyer_id | string <uuid> Get a single buyer with full offer history |
| external_ref | string List all your buyers carrying this exact external reference. See the Buyer Tracking guide. |
| offer_status | string Enum: "pending" "accepted" "declined" "fee_paid" Optional. In list modes only, return only buyers whose latest offer has this status. Buyers with no offers are excluded when this filter is set. |
{- "data": [
- {
- "buyer_id": "2a8aae71-324e-470e-b3d1-589903cf2f45",
- "property_id": "05003a8a-8f3c-454b-8884-a906ec46f5f5",
- "first_name": "string",
- "last_name": "string",
- "phone_number": "string",
- "email_address": "string",
- "purchase_purpose": "string",
- "financing_method": "string",
- "has_property_to_sell": true,
- "money_from_abroad": true,
- "wants_solicitor_quote": true,
- "external_ref": "string",
- "company": {
- "name": "Acme Holdings Ltd",
- "number": "12345678"
}, - "co_buyer_count": 1,
- "created_at": "2019-08-24T14:15:22Z",
- "latest_offer": {
- "offer_id": "d5a7a5b7-a4a3-49e7-9c69-b44d2cbe15cf",
- "amount": 250000,
- "status": "pending",
- "created_at": "2019-08-24T14:15:22Z"
}
}
], - "request_id": "266ea41d-adf5-480b-af50-15b940c2b846"
}Returns every enum/list value the API accepts or returns. Use this to populate dropdowns, validate inputs, or stay in sync with supported values. No authentication required.
{- "data": {
- "referral_statuses": [
- "string"
], - "referral_types": [
- "string"
], - "property_types": [
- "string"
], - "tenure_types": [
- "string"
], - "sale_types": [
- "auction"
], - "bedroom_options": [
- "string"
], - "bathroom_options": [
- "string"
], - "property_status_categories": [
- "string"
], - "property_milestones": [
- "agreement_sent"
], - "offer_statuses": [
- "pending"
], - "document_types": [
- "seller_agreement"
], - "webhook_event_types": [
- "string"
]
}, - "request_id": "266ea41d-adf5-480b-af50-15b940c2b846"
}Returns a short-lived signed URL (120 seconds) for downloading the document. Each access is audit-logged.
The document_id must be provided as a path parameter.
| document_id required | string <uuid> |
{- "request_id": "string"
}Returns subscriptions scoped to the authenticated OAuth client. Each client manages its own independent set of webhook subscriptions.
{- "data": [
- {
- "subscription_id": "aa11a4c2-a467-43db-b413-c4ab0f5cf627",
- "events": [
- "string"
], - "secret": "string",
- "is_active": true,
- "created_at": "2019-08-24T14:15:22Z"
}
], - "request_id": "string"
}Register a URL to receive event notifications. The secret (prefixed whsec_) is returned
once on creation — store it securely for signature verification.
Subscriptions are scoped per OAuth client.
| url required | string <uri> Must be a public HTTPS URL (no localhost, private IPs, |
| events required | Array of strings Items Enum: "referral.created" "referral.status_changed" "property.status_changed" "property.milestone_completed" "property.document_added" "property.marketplace_updated" "buyer.created" "buyer.offer_updated" |
{- "events": [
- "referral.created"
]
}{- "data": {
- "subscription_id": "aa11a4c2-a467-43db-b413-c4ab0f5cf627",
- "events": [
- "string"
], - "secret": "string",
- "is_active": true,
- "created_at": "2019-08-24T14:15:22Z"
}, - "request_id": "string"
}