Marketplace External API
Developer guide for the currently implemented Marketplace external HTTP API. This page reflects the published OpenAPI specification and verified route behavior. Admin-only endpoints are not documented here.
Overview
The external API supports public API access applications, provider integrations, API-app access requests, and API-app external case intake. Several write paths are deferred today: they authenticate, authorize, and record audit or idempotency records but do not create or update listing rows, case rows, or access-request rows in business tables.
Exception: POST /api/marketplace/api-apps/cases persists an external case intake row and may create a real user account and case when the payload passes strict validation. Invalid payloads are held for administrator review.
Base URL and versioning
- Base URL: same origin as your deployed Marketplace application.
- API version: 1.0.0 (see OpenAPI info.version).
- Path prefix: all external routes are under /api/marketplace/.
Authentication
API app key
Used by POST /api/marketplace/api-apps/access-requests and POST /api/marketplace/api-apps/cases.
- Send
x-api-app-keyorAuthorization: Bearer <token>. - Optional
x-api-app-idheader may accompany the key. - Optional
idempotency-keyheader on supported write operations. - No additional permission scope is enforced on case intake beyond API app authentication (same as access-requests intake).
Provider Bearer token
Provider routes require Authorization: Bearer with scoped permissions such as listings_write, access_requests_decide, and webhooks_receive. See the OpenAPI specification for per-operation scope requirements.
Obtaining API access
- Submit
POST /api/marketplace/api-access/applicationswith company and integration details. Returns 202 with application_id and status pending. - An administrator reviews the application via internal admin tooling.
- After approval, an administrator issues an API app key exactly once. Integrators must copy and store the issued token immediately; it is not shown again.
Idempotency
Many write operations accept an idempotency-key HTTP header. The first request with a key stores the payload hash. Repeating the same key with the same payload is replay-safe. The same key with a different payload returns 409 (conflict).
For case intake, when external_case_id is present in the JSON body, repeating the same api_app_id + external_case_id pair returns 200 with the existing intake_id and status instead of creating a duplicate row.
Submitting a case
POST /api/marketplace/api-apps/cases stores an external case intake row. When the payload passes strict validation, the server auto-creates a marketplace user account and case. Invalid payloads are stored with status held_for_review and require administrator approval before conversion.
Request body fields
| Field | Required for auto-convert | Description |
|---|---|---|
| title | Yes | Case title (max 300 characters after normalization) |
| party_email | Yes | Party email (valid shape; max 320 characters) |
| party_name | No | Party display name (max 200 characters) |
| summary | No | Case summary (max 4000 characters) |
| external_case_id | No | Caller-supplied identifier (max 200 characters); used for deduplication |
| Additional keys | No | Arbitrary extra shared-information fields preserved in the stored payload |
Response shapes
- 202 converted:
{ intake_id, status: "converted", case_id } - 202 held_for_review:
{ intake_id, status: "held_for_review", validation_errors } - 202 failed:
{ intake_id, status: "failed", error, code }(generic error message) - 200 replay:
{ intake_id, status }when external_case_id dedupes an existing intake - 401 / 403 authentication failure; 405 for non-POST methods
Validation error codes
title_required— title missing or empty after normalizationtitle_too_long— title exceeds 300 charactersparty_email_required— party_email missing or emptyparty_email_invalid— party_email fails shape validationparty_email_too_long— party_email exceeds 320 characterssummary_too_long— summary exceeds 4000 charactersparty_name_too_long— party_name exceeds 200 charactersexternal_case_id_too_long— external_case_id exceeds 200 characters
Other endpoints (summary)
POST /api/marketplace/api-access/applications— public signup intake (202 pending).POST /api/marketplace/api-apps/access-requests— deferred access-request artifact (no business row mutation today).POST /api/marketplace/providers/listings— deferred listing write envelope (no listing mutation today).POST /api/marketplace/webhooks/provider— inbound webhook with HMAC signature verification (audit/outbox only).
Do not assume that a 202 response on deferred routes means a listing or case was created or updated. See the OpenAPI specification for full request and response details.