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.

OpenAPI specification (JSON)

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-key or Authorization: Bearer <token>.
  • Optional x-api-app-id header may accompany the key.
  • Optional idempotency-key header 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

  1. Submit POST /api/marketplace/api-access/applications with company and integration details. Returns 202 with application_id and status pending.
  2. An administrator reviews the application via internal admin tooling.
  3. 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

FieldRequired for auto-convertDescription
titleYesCase title (max 300 characters after normalization)
party_emailYesParty email (valid shape; max 320 characters)
party_nameNoParty display name (max 200 characters)
summaryNoCase summary (max 4000 characters)
external_case_idNoCaller-supplied identifier (max 200 characters); used for deduplication
Additional keysNoArbitrary 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 normalization
  • title_too_long — title exceeds 300 characters
  • party_email_required — party_email missing or empty
  • party_email_invalid — party_email fails shape validation
  • party_email_too_long — party_email exceeds 320 characters
  • summary_too_long — summary exceeds 4000 characters
  • party_name_too_long — party_name exceeds 200 characters
  • external_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.