Partner API

Send us an opportunity. We'll handle intake, dedupe, and conversion.

One canonical pipeline behind three transports, so a partner with a full engineering team and a partner with none both land in the same review queue with the same field set. This page documents what exists today -- if something below isn't listed, it isn't built yet.

Getting access

Credentials are issued by BayLineup staff today -- apply here and we'll set up whichever transport fits your integration. There is no self-service signup yet.

Transports

Pick whichever matches your engineering resources. All three create the same kind of record and land in the same staff review queue.

TransportWhen to use itAuth
REST APIYou have an API/integration team and want programmatic control (idempotency, immediate response).Scoped API key (Authorization: Bearer)
Signed webhookYou already run your own event delivery and just need a URL + secret to push to.HMAC-SHA256 request signature
Secure Partner FormYou have no API or engineering resources at all -- a no-login web form your staff fill in by hand.Possessing the form's link (high-entropy token)

REST API

POST /api/partners/v1/opportunities

Authenticate with Authorization: Bearer <api key>. Your key needs the partner_intake:write scope. Pass an Idempotency-Key header on every request -- retrying the same key returns the original result (200, deduped: true) instead of creating a duplicate opportunity.

POST /api/partners/v1/opportunities
Authorization: Bearer <api key>
Idempotency-Key: <your own UUID for this submission>
Content-Type: application/json

{
  "externalId": "your-system's-id-for-this-lead",
  "customerName": "Jamie Rivera",
  "customerPhone": "5551234567",
  "vehicleMake": "Honda",
  "vehicleModel": "Civic",
  "vehicleYear": 2019,
  "complaint": "Brakes squealing",
  "requestedTiming": "This week"
}

Responses:

201 Created                       -- new opportunity
{ "opportunity": { "id": "...", "orgId": "...", "partnerKey": "...", "status": "received", ... }, "deduped": false }

200 OK                            -- same Idempotency-Key seen before
{ "opportunity": { ... }, "deduped": true }

400 Bad Request                   -- validation failed (e.g. no customer info at all)
401 Unauthorized                  -- missing/invalid key
403 Forbidden                     -- key lacks partner_intake:write
429 Too Many Requests             -- rate limit or concurrency limit (see below)

Sandbox & testing

GET /api/partners/sandbox/fixtures

Ask BayLineup for a sandbox key (prefixed blp_test_ instead of blp_live_) to exercise the real intake/dedupe/validation pipeline with test data. Sandbox activity never appears in real ops metrics and can never create a real customer record -- a converted sandbox opportunity is simulated end-to-end, including a real signed outbound event to any subscription you have configured, without ever touching production data.

A live fixture library of ready-to-send request bodies -- valid, malformed, duplicate/idempotency-retry, and empty-submission cases -- is served at the endpoint above, so your own test suite can pull them directly instead of copy-pasting from this page.

Signed webhook (inbound)

POST /api/partners/webhooks/{orgId}/{partnerKey} -- the URL and shared secret are issued when your webhook is set up.

Sign the raw request body with your secret and send the result as X-BayLineup-Partner-Signature:

signature = hex(HMAC-SHA256(secret, rawRequestBody))

Same JSON body shape as the REST API above. Send a stable X-BayLineup-Delivery-Id header (your own delivery/event ID) on every attempt -- retried deliveries with the same ID are acknowledged as duplicates without reprocessing, so retrying on a timeout is always safe. A request with a bad or missing signature is recorded and rejected with 401; an unconfigured URL returns 404 rather than confirming whether a partner key exists.

Outbound events

Subscribe to be notified when an opportunity you sent us is decided. Deliveries are signed the same way as the inbound webhook (HMAC-SHA256 over the raw body, same header), with automatic retry and an idempotency key per delivery.

Event typeFires when
opportunity.convertedStaff accepted your opportunity and it became a customer/vehicle record.
opportunity.declinedStaff declined your opportunity, with a reason.
opportunity.duplicateStaff marked your opportunity a duplicate of an existing one.

Field reference

Every field is optional individually, but a submission needs at least one piece of real customer or vehicle content -- an entirely empty payload is rejected.

FieldTypeNotes
externalIdstringYour own ID for this lead -- resubmitting the same externalId updates rather than duplicates it.
referralIdstringYour campaign/referral tracking ID, if any.
customerNamestring 
customerPhonestringUsed for duplicate/existing-customer matching.
customerEmailstring 
vehicleYearnumber 
vehicleMake / vehicleModel / vehicleVinstring 
complaintstringWhat the customer reported.
requestedTimingstringFree text -- "today", "this week", etc.
quoteReferenceobjectYour own quote/estimate metadata, passed through as-is.
notesstring 
attachmentsstring[]URLs only -- no file upload endpoint.
consentMetadataobjectRecord of what the customer consented to share, if applicable.

Rate limits & errors

TransportSustainedConcurrent in-flight
REST API / Secure Partner Form120 requests/minute10
Signed webhook300 requests/minute20

A 429 response includes Retry-After. These are engineering defaults we can raise for a high-volume partner after a load/security review -- not a hard commercial cap.

Ready to send us your first opportunity?