Skip to main content

Marketplace requests: from request to fulfillment

A marketplace request is the work queue between an operator who needs a marketplace resource and a developer or vendor who can deliver it. The request workflow keeps the hand-off visible: the operator describes the outcome, a published listing is matched, a developer claims the work, and the operator confirms delivery. This guide covers the dashboard workflow and the API calls behind it. You need an authenticated workspace session or an API key with the role required by your organization. Requests are scoped to the organization that creates them; do not put API keys, webhook secrets, or other credentials in a request description.

The two roles

The workflow has two views of the same request: An operator owns the request lifecycle. A developer can work on a request only after claiming it, and the operator remains the person who confirms that the delivery meets the request.

Where the surface lives

In the dashboard, open Developer → Marketplace and select the Requests tile. Operators use Requests to create and follow requests. Developers use the same tile to review requests that match listings published by their organization. The Requests tile is next to the marketplace catalog, not a replacement for it. Start with Browse, install, and publish marketplace templates when you want to browse or install a published template, or publish a listing before accepting requests. Use this guide when a request needs a developer to deliver or adapt work for an operator.

The request loop

The following walkthrough mirrors the dashboard: each screen shows the state after the action, followed by the API transition that produced it. Replace the example IDs with the IDs returned by your workspace.

1. Operator creates a request

Screen: Requests → New request. Enter a clear outcome, constraints, and the type of marketplace resource you need. Submit the form. The new request appears in the operator’s list with state open.
Save the returned data.id. It is the request ID used by every later transition.

2. Operator matches a template

Screen: Request detail → Match listing. Search the published marketplace, inspect the listing configuration, and attach the listing that best fits the request. A match does not install the listing or commit either party to delivery; it gives developers the context they need before claiming the work.
The request stays visible to the operator and becomes eligible for the developer organization that owns the matched listing.

3. Developer claims the request

Screen: Requests → Available. The developer reviews the request, the matched listing, and the delivery deadline. Select Claim only when your organization can complete the work before the claim expires.
A successful claim changes the request to claimed and records the claiming organization. A second developer cannot claim the same request after the first claim succeeds.

4. Developer delivers

Screen: Request detail → Deliver. Attach the resulting resource or provide the delivery reference and a short explanation of what changed. Keep credentials out of the delivery notes.
The request changes to delivered. The operator receives the delivery in the request detail view and can review the referenced resource before confirming it.

5. Operator confirms

Screen: Request detail → Confirm delivery. Test the delivered resource in your workspace. Select Confirm when it meets the request.
Confirmation moves the request to completed, the terminal success state. If the delivery is not correct, do not confirm it; use the request detail and the developer’s delivery notes to resolve the issue before confirming.

State machine

The request states are the values used by the marketplace-request route contract. The route index is the source of truth for the current transition guard: apps/api/src/routes/marketplace-requests/index.ts. Treat the response state as authoritative. A stale Requests page can still show an earlier state while another actor is acting; reload the request before retrying a transition.

Repeated creates and safe retries

Create requests with an idempotency key. If the browser loses its connection after submitting, repeat the same create with the same key instead of opening a second request:
A repeated create with the same idempotency key and equivalent payload returns the original request rather than creating a duplicate. Use a new key for a genuinely new request. Do not reuse a key after changing the requested outcome. The same retry rule applies to transition calls: keep the request ID, inspect the current request state, and retry only when the requested transition is still valid. A successful transition is not undone by an HTTP retry.

Timeouts, expiry, and failure semantics

The request pipeline has timeout and expiry handling for both an unclaimed request and a claimed request. The Requests tile reflects these outcomes instead of leaving a request in an in-progress state indefinitely:
  • An open or matched request that reaches its request deadline becomes expired without being claimable.
  • A claimed request has a claim deadline. If the developer does not deliver before that deadline, the claim expires and the request is no longer fulfilled by that claim.
  • A delivery or confirmation request that races with expiry returns the current-state error. Refresh the detail view before deciding whether to retry.
  • A transient request failure does not mean that a transition happened. Fetch the request by ID and use its returned state as the source of truth.
The timeout and notification services behind this behavior also notify the relevant party when a request or claim is approaching expiry. They do not bypass tenant ownership or install a listing automatically. The operator still confirms the delivered resource.

Edge cases

No matching template

If the marketplace has no published listing that fits the request, leave the request open and refine the description or constraints. Do not attach an unrelated listing just to move the request forward. You can cancel the request and create a new one when the requirement has changed.

Expired claim

An expired claim cannot deliver or confirm. The request remains governed by its current state and deadline rules; if it is still eligible for another claim, the Requests tile exposes it again for matching developers. If it is expired, create a new request rather than retrying the old claim.

Cancelled request

Cancel before confirming when the work is no longer needed. A cancelled request is terminal: it cannot be claimed, delivered, or confirmed. If the same work becomes necessary later, create a new request with a new idempotency key.

Transition rejected

A 409 or state-transition error means another actor changed the request, or the request reached a terminal state. Retrieve the request, compare its state with the table above, and continue from the dashboard only if the next action is valid. Do not replay a claim or delivery against a terminal request.