Skip to main content
Four calls, end to end, in the language you are going to write this in. Each script below does the same four things and handles the two failures every integration meets on day one: a token that expired (401) and a ceiling you hit (429). You need an API key for a sandbox workspace — Get access — and one environment variable:
There is no SDK. Every sample here is the standard HTTP client of its own language against the published contract — that is deliberate, and it is why the four scripts are the same length.

Or import the collection

If you would rather press Send than run a script, import the Postman collection — all 48 operations, foldered by tag, with the request bodies from this document already filled in. Set the apiKey variable, run Exchange your API key for a token once, and every other request is authorized from the token it stores. It is generated from the OpenAPI document and checked against it on every build, so it cannot describe a contract we no longer serve. The document itself is at /openapi/openapi.yaml if your tooling would rather have that.

What the scripts do

1

Exchange the key for a token

POST /v1/token. The body is empty: the workspace, the environment and your scopes all come from the key. Read sandbox in the response to confirm which tenancy you are in.
2

Read your catalogue

GET /v1/properties. Empty on a fresh sandbox — that is the correct answer, not a failure.
3

Push a property

PUT /v1/properties/{provider_id}, keyed by your own identifier, so a retry lands on the same row.
4

Register a webhook endpoint

PUT /v1/webhooks/endpoint. We POST a signed endpoint.challenge to the URL during this call and your handler must echo it back — until it does, the endpoint is pending_verification and nothing is delivered. Webhooks has the verifier.

The script

What you should see

  • Step 1 returns sandbox: true and a scope array. If sandbox is false you hold a production key, and every contract call below will answer 501 not_enabled after authenticating and validating in full — see Environments.
  • Step 2 returns {"items": [], "has_more": false} on a fresh sandbox.
  • Step 3 returns result: "created" the first time and result: "updated" every time after, because the URL carries your own identifier. publishable and missing say whether the property can go on sale — a first push usually comes back missing: ["cover_photo", "photos"].
  • Step 4 leaves the endpoint pending_verification unless your handler echoed the challenge. That is the one step you cannot complete without writing a receiver first.

When it does not work

Every one of those is a problem document with a code to branch on — Errors.