cypress.DOCS
Log inRegister
Cypress Docs
Developers

Quickstart

From an API key to your first signed webhook in about fifteen minutes.

TL;DRAI summary

This chapter quickly guides you through setting up Cypress using your API key and a webhook receiver. You'll then push a vehicle to market and see how the platform automatically handles the sale process for you.

Dive deeper:

Everything here runs against staging first (https://staging.app.getcypress.ai) with credentials issued for your organization — same flow in production when you're ready.

Connecting an AI agent instead?

Agents connect over MCP, not by hand-written requests: the MCP quickstart gets one working in a sandbox in ten minutes.

Fifteen minutes, honestly

Steps 1–4 are the whole integration loop: credentials, a client, a receiver, one push. Everything after is the platform working while your terminal narrates.

1. Get your credentials

From the Integrations page in your Cypress dashboard (or ask your Cypress manager):

  • an API key (cyp_live_…) — shown once at mint; send it as x-api-key on every call,
  • a signing secret — issued when your webhook subscription is created; verifies our deliveries.

Check the key:

curl "$BASE/api/v1/organization" -H "x-api-key: $KEY"

It lists what the key may do and why not — see Your organization and key.

A key holds only the scopes your organization's admin gave it on the Integrations page: vehicles, listings and webhooks for this quickstart, and one pair (:read, :write) for each further area: offers, tasks, the CRM, closings, marketing, automations, planning and more. A route outside the key's scopes answers 403 SCOPE_MISSING, and the admin adds the scope without rotating the key. The whole list is in Key scopes.

Building an app or an agent, not a bridge?

An API key acts as your own organization. An app that other organizations connect, or an AI agent, uses Connect Cypress (an admin approves it, and its tokens carry the scopes it asked for) or the MCP servers. To build against a world that is not a real fleet, ask for a sandbox: an organization with vehicles, a CRM book and a buy plan already in it, and a key with every scope.

2. Pick your client

  • Postman / Bruno / Insomnia (Import) — import the ready-made collection: cypress-postman-collection.json (Postman v2.1 format — all three clients read it). All 118 requests are numbered in flow order, carry example payloads, and capture ids (vehicleId, listingId, …) into collection variables automatically. Set apiKey and baseUrl on the collection variables after importing.
  • Bruno (native) — download cypress-bruno-collection.zip, unzip it, then use Collection → Open Collection and select the extracted folder. Don't drag the zip into the Import dialog — Bruno's importer reads JSON exports (like the Postman collection above), not zipped .bru folders. The native collection adds localhost/staging environments.
  • OpenAPI — the full machine-readable spec lives at /api/public/openapi.json if you'd rather generate a client or import the raw schema.
  • curl — every example below is copy-paste ready.

3. Stand up a webhook receiver (2 minutes)

Download the debug receiver: webhook-receiver.mjs — a zero-dependency Node script that prints every envelope with ✓/✗ badges for your header and the HMAC signature:

PORT=9099 \
EXPECT_API_KEY=<the header value your endpoint expects> \
SIGNING_SECRET=<your signing secret> \
node webhook-receiver.mjs

Expose it to Cypress (any tunnel works — ngrok http 9099, cloudflared, …) and register the HTTPS URL as your subscription callback — or ask Cypress to point your existing subscription at it. Then send a test event:

curl -X POST "$BASE/api/v1/webhooks/subscriptions/$SUB_ID/test" \
  -H "x-api-key: $KEY"

A PING.TEST envelope lands in your terminal, signature verified.

4. Push a vehicle — straight to market

curl -X POST "$BASE/api/v1/vehicles" \
  -H "x-api-key: $KEY" -H "content-type: application/json" \
  -d '{
    "vin": "1FTFW1ET5DFC10312",
    "modelYear": 2013, "make": "Ford", "model": "F-150",
    "mileage": 88500,
    "listing": { "buyNowPrice": 22500, "floorPrice": 18000,
                 "listingMode": "IMMEDIATE" }
  }'

One request: the vehicle is created, priced, and live on the marketplace ("launched": true). Your terminal shows VEHICLES.CREATED, LISTINGS.CREATED, LISTINGS.ACTIVATED arriving within seconds.

The response echoes the vehicle, trimmed here to the fields that matter first:

{
  "vehicle": {
    "id": "clx…",
    "vin": "1FTFW1ET5DFC10312",
    "status": "LISTED",
    "lifeStage": "REMARKETING",
    "pricing": { "buyNowPrice": 22500, "floorPrice": 18000, "startBidPrice": null }
  },
  "listing": { "id": "clx…", "status": "ACTIVE", "channels": ["MARKETPLACE"] },
  "launched": true
}

status is where the vehicle is in the sale; lifeStage is where it is in its life — see Vehicle lifecycle. If a push is refused, the body says why in error, and a stable code when there is one — see Errors.

Prefer the Manheim shape? The same push works at /api/compatible/v1/units with a description/odometer payload — see the API reference.

5. Watch a sale happen

From here the platform drives and your terminal narrates: a buyer's offer (OFFERS.CREATED), the acceptance (OFFERS.ACCEPTED, CLOSING.STARTED), the signed bill of sale (CLOSING.DOCUMENT.SIGNED with a document link), payment (CLOSING.PAYMENT.RECEIVED), and the finale — LISTINGS.PURCHASED with the sale price.

Flip the receiver into fail mode (curl -X POST localhost:9099/_toggle-fail) to watch retries and dead-lettering behave exactly as documented.

6. Where to go next