Use the partner API when a marketplace needs to give a customer a workspace and track a rented agent's work. Each job is represented by an engagement: a bounded record connecting the marketplace, workspace, and execution trace. Your marketplace authenticates with an mpk_ partner key; the rented runtime gets a separate short-lived token limited to appending its own engagement events.
Partner, runtime, workspace, and browser identities differ
The mpk_ key manages linked workspaces and engagements but cannot read workspace traces. An engagement token works only on one append URL and has no read/finalize authority. Workspace agk_ keys use the ordinary machine plane, while SSO handoffs are 120-second single-use browser credentials.
An engagement is the authorization boundary
It binds one hiring to one workspace trace. Runtime and partner event routes select that trace from the engagement row, not caller input; stable source_event_id values deduplicate events, and closing increments the epoch so outstanding runtime tokens stop immediately.
Runtime and commercial outcomes are separate
Closing records the immutable runtime outcome and finalizes the trace. Later open, settled, disputed, or refunded commercial events form a revision-ordered history without rewriting what the runtime did.
Before you begin
The command-line examples require curl and jq; any exception is identified in its introduction.
A marketplace partner credential (mpk_) provisioned with only the needed workspaces:provision, sso:handoff, webhooks:manage, or engagements:manage scopes.
Stable external user, workspace, engagement, and commercial-event identifiers owned by the marketplace.
A secure server-side store for partner keys, webhook signing secrets, and short-lived engagement tokens.
How it works
Provision or reconnect the workspace
POST the stable external user/workspace mapping. First contact creates the managed workspace and bridge agent; repeats link or reactivate the same mapping without issuing a long-lived workspace key.
Open one engagement per hiring
Use the partner's stable hiring ID, retain the returned engagement and trace IDs, then mint a runtime token with a TTL no longer than seven days or the engagement's own expiry.
Append, reconcile, and close
The runtime posts bounded event batches to its events URL; the partner uses its own scoped routes for server-observed events and status reconciliation. Close once with the final runtime status, then record commercial transitions separately.
Examples
These examples are illustrative. Replace the sample values with your own.
Keep credentials in environment variables or a secret manager, never in client-side code.
Provision a marketplace-linked workspace
Repeating the same stable mapping links the existing workspace instead of creating another.
First contact returns HTTP 201 with status: created; repeats return 200 with status: linked. Both include user, workspace, slug, and bridge service-agent IDs but no workspace API key.
Open an engagement and mint its runtime token
The partner key creates and mints; only the returned engagement token belongs on the runtime events URL.
Engagement creation returns 201 or idempotent 200. Token mint returns 201 with an opaque token, engagement ID, expiry, engagement:append, and the only URL that token can call.
Troubleshooting
Partner errors use two response families
Named partner authentication, authorization, lifecycle, and engagement errors use bare {"error": "code"} bodies. Validation changesets rendered by the shared fallback and 429 responses from the authentication-failure or principal rate limiter use the shared problem JSON shape, so branch on both HTTP status and content type rather than assuming every partner error is bare.
A runtime receives 401 or 403
Stop blind retries and inspect the code. Invalid, expired, revoked, or closed/expired engagement tokens need partner remediation and, where the engagement is still active, a newly minted token. engagement_mismatch means a valid token was sent to the wrong engagement URL; pair that token with its returned engagement_id and events_url instead. insufficient_scope requires a correctly authorized token.
A partner key cannot read the trace
This is intentional isolation. Reconcile through partner engagement/status and webhook routes; an mpk_ credential is not accepted by GET /api/v1/traces/:id.
A webhook retry creates a conflict
Partner webhook-subscription idempotency lasts 24 hours for the exact body. Reusing the same key with changed URL or event types returns idempotency_conflict.
Endpoint reference
Ready to integrate? Open an endpoint for its required permissions, request fields,
response format, and status codes. The examples above explain the workflow;
these details define each individual request.
POST
/api/v1/partner/workspaces
partner token
Provision or link a marketplace workspace
workspaces:provision
Description
PartnerAuth: Authorization: Bearer mpk_… (not an agk_ workspace key). Idempotent find-or-link workspace provisioning for a marketplace partner user. On first contact it creates the user, workspace and bridge service agent; on repeat calls it links, and a previously disconnected link is reactivated. No long-lived key is issued: runtimes are credentialed per engagement. Created workspaces write settings.quota_overrides.traces_per_month = infinity so sponsored ingest never 429s mid-hire; other quota dimensions stay on the workspace plan. The workspace is marketplace-managed: invitations are refused (marketplace_managed_workspace) and it stays single-member.
Auth
partner token
Required Scopes
workspaces:provision
Request Body
Field
Type
Required
Description
name
string
No
Display name
email
string
Yes
Human email, stored on the identity account (never the login address)
workspace
object
Yes
Workspace mapping: external_ref (stable key) and name
external_user_id
string
Yes
The marketplace's stable user UUID
Responses
200
Already linked; identical fields to the created response
PartnerAuth: Authorization: Bearer mpk_…. Revokes every credential the partner holds in the workspace: active engagements are revoked, legacy bridge credentials and the bridge service agent are revoked, partner webhook subscriptions are disabled and the linked user's browser sessions are cut. The workspace, user, membership and identity provider are untouched — they are the user's own account — and the link row is kept as disconnected so a later provision call reconnects to the same workspace.
PartnerAuth failed. Body is {error: "invalid_partner_credential"}
403
Partner lacks workspaces:provision. Body is {error: "insufficient_partner_scope"}
404
Body is {error: "identity_not_linked"}
POST
/api/v1/partner/sso_handoffs
partner token
Mint a single-use browser SSO handoff
sso:handoff
Description
PartnerAuth: Authorization: Bearer mpk_…. Mints a 120-second, single-use handoff URL that logs the linked marketplace user into their workspace and redirects to return_to (must start with /app).
Register a webhook subscription on a linked workspace
webhooks:manage
Description
PartnerAuth: Authorization: Bearer mpk_…. Creates a webhook subscription in the linked workspace and returns the HMAC signing secret. Supply an Idempotency-Key to make exact retries replay the same subscription and secret for 24 hours; reusing the key with a different body returns 409. Without the header, every request creates a new subscription. Omitted event_types default to trace.event.appended and trace.finalized only — not failure_group.created. Reconciliation is webhooks only: an mpk_ key cannot GET /api/v1/traces/:id.
Auth
partner token
Required Scopes
webhooks:manage
Request Body
Field
Type
Required
Description
url
string
Yes
HTTPS delivery URL
event_types
array<object>
No
Event type filters. Defaults to ["trace.event.appended", "trace.finalized"] when omitted. failure_group.created is not in the default set.
external_ref
string
Yes
Workspace mapping key used at provisioning
Parameters
Name
In
Type
Required
Description
Idempotency-Key
header
string
No
Partner-scoped exact-retry key retained for 24 hours
Responses
200
Exact Idempotency-Key replay; same subscription and secret
PartnerAuth failed. Body is {error: "invalid_partner_credential"}
403
Partner lacks webhooks:manage. Body is {error: "insufficient_partner_scope"}
404
Body is {error: "identity_not_linked"}
409
Idempotency-Key was reused with a different body. Body is {error: "idempotency_conflict"}
422
Idempotency-Key is blank, duplicated, contains non-visible ASCII, or exceeds 200 bytes
POST
/api/v1/partner/engagements
partner token
Open the engagement for one marketplace hiring
engagements:manage
Description
PartnerAuth: Authorization: Bearer mpk_…. Idempotent per (partner, external_engagement_ref). Creates or adopts the trace for this hiring and binds it to an engagement row. The engagement is the unit of authorization: it is what a runtime token names, and the trace a runtime may append to is read from this row rather than from the runtime's request.
PartnerAuth: Authorization: Bearer mpk_…. Returns the only credential a rented runtime ever holds: append-only, bound to one engagement and one trace, and dead the moment the engagement is closed or revoked. It authenticates on events_url via EngagementAuth and nowhere else. TTL defaults to 86400 seconds, is clamped to the engagement's own expiry, and is hard-capped at 604800 seconds (7 days). A 30-day engagement cannot mint a 30-day token.
Auth
partner token
Required Scopes
engagements:manage
Request Body
Field
Type
Required
Description
ttl_seconds
integer
No
Must be positive when present. Defaults to 86400. Clamped to the engagement's own expiry and hard-capped at 604800 seconds (7 days).
Append events to an engagement's trace (marketplace)
engagements:manage
Description
PartnerAuth: Authorization: Bearer mpk_…. The marketplace's own server-side export leg, for events it observes rather than the runtime does. Events land on the trace named by the engagement row; a trace_id in the body is refused on mismatch and is never used to select a target. Retries are safe: an event whose source_event_id the trace already holds is counted as a duplicate rather than appended twice.
Auth
partner token
Required Scopes
engagements:manage
Request Body
Field
Type
Required
Description
events
array<object>
Yes
Up to 50 events; each needs a stable source_event_id of at most 128 bytes
Parameters
Name
In
Type
Required
Description
id
path
string
Yes
Engagement UUID
Responses
200
Events appended
Example
{
"rejected": 0,
"accepted": 3,
"duplicates": 1
}
401
PartnerAuth failed. Body is {error: "invalid_partner_credential"}
403
Partner lacks engagements:manage ({error: "insufficient_partner_scope"}), or {error: "engagement_mismatch"}
EngagementAuth: Authorization: Bearer <engagement token> only. A workspace agk_ key fails signature verification; an mpk_ partner key is not accepted. The rented runtime's entire authority. Append-only: there is no read, no list, no finalize and no trace id in the path, because the trace written to is read from the engagement row. Errors are {error: code}, not RFC 9457. 401 from the plug (invalid_token, token_expired, token_revoked, engagement_closed, engagement_expired) and 403 from the controller (engagement_mismatch, insufficient_scope) are terminal — stop exporting.
Auth
engagement token
Required Scopes
engagement:append
Request Body
Field
Type
Required
Description
events
array<object>
Yes
Up to 50 events; each needs a stable source_event_id of at most 128 bytes
Parameters
Name
In
Type
Required
Description
engagement_id
path
string
Yes
Engagement UUID; must match the one the token names
Responses
200
Events appended
Example
{
"rejected": 0,
"accepted": 3,
"duplicates": 1
}
401
{error: "invalid_token"|"token_expired"|"token_revoked"|"engagement_closed"|"engagement_expired"} — all terminal; stop exporting
403
{error: "engagement_mismatch"} or {error: "insufficient_scope"}
413
{error: "too_many_events"}
422
{error: "invalid_events"}
GET
/api/v1/partner/engagements
partner token
Reconcile marketplace engagements
engagements:manage
Description
PartnerAuth with engagements:manage. Returns only partner-owned operational status; it never returns event or payload bodies. Results use an opaque updated_at/id cursor.
Auth
partner token
Required Scopes
engagements:manage
Parameters
Name
In
Type
Required
Description
cursor
query
string
No
limit
query
integer
No
status
query
string
No
external_ref
query
string
No
external_engagement_ref
query
string
No
Responses
200
Partner engagement page
400
Invalid cursor
401
Invalid partner credential
403
Insufficient partner scope
GET
/api/v1/partner/engagements/:id
partner token
Read marketplace engagement status
engagements:manage
Description
Partner-scoped operational status including immutable runtime outcome and the separate commercial projection.
Partner-scoped, revision-ordered commercial event history. Use after_revision and the returned next_after_revision for bounded pagination. Event metadata and internal request hashes are never returned.
PartnerAuth: Authorization: Bearer mpk_…. Finalizes the bound trace with a terminal status and bumps the engagement epoch, so every outstanding runtime token for this hiring is refused at its next request. Idempotent. EngagementExpiryWorker also closes still-active engagements 900 seconds after expires_at as final_status partial and bumps the epoch the same way.