Skip to Content
Task guidesTechnical: Use Cases

Use Cases

Technical reference. This page is for integrations, advanced configuration, or platform operations. For portal tasks, start with the user guide.

A use case turns a plain-language description of a business problem into a runnable, reviewable, publishable bundle — a flow plus the prompt, model policy, policy bundle, and connections it needs — without hand-assembling each piece yourself.

How It Works

  1. Describe what you want in plain language (for example, “Triage incoming refund requests and flag anything over $500 for review”).
  2. Orqestra drafts a bundle: an orchestration flow, a prompt, a reference to an approved model policy, a policy bundle, and any connections the flow needs. If your description leaves something ambiguous, you’re asked a short clarifying question first.
  3. Review the draft: a plain-language summary of what it does, a worked “try it” example, and a “show me what you built” panel that opens each piece in its real editor.
  4. Publish. If every connection the bundle needs already exists and you’re allowed to use it, the use case goes live immediately. If a connection doesn’t exist yet and you can’t create it yourself, publish still succeeds — the use case moves to a pending state while a request goes to your platform team.
  5. Once your platform team grants the request, the connection is set up and the use case activates automatically — no separate step on your part.

The generated flow, prompt, and other pieces follow the same shape as hand-authored assets and can be edited normally once you open them.

Using the API

Generate a draft

POST /v1/use-cases/generate is pure — it never creates anything. It either returns a bundle plan plus a preview of any access gaps, or a needs_clarification response with a follow-up question.

This uses the same governed platform-generator family as asset and flow drafting. Orqestra resolves the active production generator release server-side, requires a synchronous runtime result, validates the nested bundle plan, and persists nothing on this route. The generator runs under its own system credential, provisioned automatically at startup — you do not need a principal binding of your own on the generator workload; authorization is decided against the target workspace. Missing target-workspace permission or a policy denial returns 403, a queued-only runtime returns 409 inline_dispatch_unavailable, and a generator that has no active release or is not fully provisioned returns 503.

curl -X POST "/v1/use-cases/generate?workspace_id=$WORKSPACE_ID" \ -H "Content-Type: application/json" \ -d '{ "description": "Triage incoming refund requests and flag anything over $500 for review" }'

Response (bundle):

{ "needs_clarification": false, "bundle": { "name": "Refund Triage", "summary": "Classifies refund requests and flags high-value ones for review.", "flow": { "entry_step": "classify", "steps": [] }, "prompt_template": { "template": "Classify this refund request: {{ inputs.text }}" }, "model_policy_ref": "gpt4-standard", "connections": ["billing-crm"] }, "warnings": [], "gaps": { "model_policy": { "kind": "reused", "ref": "gpt4-standard" }, "policy_bundle": { "kind": "mint_fresh", "ref": null }, "connections": [{ "kind": "needs_access", "ref": "billing-crm" }], "redacted": false }, "generation_id": "9f43b1d1-2f7e-4d64-8b78-0f3b91a4f6f8" }

Create a draft

POST /v1/use-cases persists the bundle a generate call returned. It re-validates the bundle from scratch rather than trusting the caller’s copy.

curl -X POST "/v1/use-cases?workspace_id=$WORKSPACE_ID" \ -d '{ "source_description": "Triage incoming refund requests and flag anything over $500 for review", "bundle": { "...": "the bundle from generate" } }'

Refine a draft

POST /v1/use-cases/{use_case_id}/refine REPLACES a draft: it generates a fresh bundle from the description plus your refinement_context notes, persists it as a new use case, and archives the one you refined — superseded_by on the archived predecessor names the successor — all in a single transaction. Refining never leaves two drafts behind; exactly one current draft remains.

curl -X POST "/v1/use-cases/{use_case_id}/refine?workspace_id=$WORKSPACE_ID" \ -H "Content-Type: application/json" \ -d '{ "description": "Triage incoming refund requests and flag anything over $500 for review", "refinement_context": [{ "note": "Also post high-value ones to Slack." }], "idempotency_key": "a3f1c0f2-5b6e-4f4a-9f0c-2f2b9a1d7e11" }'

description is the original description, unchanged — the notes are applied on top of it, not instead of it. The response is the same envelope generate-and-create returns: the successor draft in use_case, or a needs_clarification question with use_case: null, in which case nothing was created and nothing archived.

idempotency_key is required, and it is what makes a refine safe to retry. Generation can take longer than a client’s timeout, so a caller may never learn that its call succeeded; retrying with the SAME key returns the same successor instead of drafting a second one. A key is additionally scoped to the predecessor it was first used against — presenting it against a different use case is a client mistake, not a retry, and returns 409 idempotency_key_conflict. Retry the same instruction with the same key; change the instruction and you need a fresh one.

Only a draft can be refined — a use case that was already replaced, published, or archived returns 409. Read superseded_by off the detail route (GET /v1/use-cases/{use_case_id}) to follow a replaced draft to its successor and refine that one instead.

List and inspect

curl "/v1/use-cases?workspace_id=$WORKSPACE_ID&status=draft" curl "/v1/use-cases/{use_case_id}?workspace_id=$WORKSPACE_ID" curl "/v1/use-cases/{use_case_id}/bundle?workspace_id=$WORKSPACE_ID"

Pass activation_ready=true instead of status to list only use cases that are pending access with every connection already resolved — the same query that drives the activation to-do described below.

bundle is the persisted bundle behind a use case: one row per piece (the flow, the prompt, the model policy, the policy bundle, and each connection) with the id you open it by, plus the bound flow’s step ids and types. It is a separate read from the detail route above because the detail route is polled while a use case is pending access, and the bundle only changes when its connections do. workspace_id is required, like the other use-case routes, and the read is gated on asset.view. A caller who holds asset.view but not connection.read gets an empty projection with redacted: true rather than a filtered one — a partial list would disclose how many connections the bundle has.

Publish, archive, reopen, activate

curl -X POST "/v1/use-cases/{use_case_id}/publish?workspace_id=$WORKSPACE_ID" curl -X POST "/v1/use-cases/{use_case_id}/archive?workspace_id=$WORKSPACE_ID" curl -X POST "/v1/use-cases/{use_case_id}/reopen?workspace_id=$WORKSPACE_ID" curl -X POST "/v1/use-cases/{use_case_id}/activate?workspace_id=$WORKSPACE_ID"

publish resolves to active (no gaps) or pending_access (a needs-access gap was routed to a fresh access request); an unreachable model policy fails with a 422 and the use case stays a draft. reopen moves a pending_access use case back to draft and withdraws its outstanding requests. activate re-runs the activation check on a pending_access use case whose connections are all resolved — the same action behind the activation to-do.

Using the SDK

async with OrqestraClient(base_url=url, api_key=key) as client: generated = await client.use_cases.generate( workspace_id=workspace_id, description="Triage incoming refund requests and flag anything over $500 for review", ) draft = await client.use_cases.create( workspace_id=workspace_id, source_description="Triage incoming refund requests and flag anything over $500 for review", bundle=generated["bundle"], ) # Refining REPLACES the draft: the successor comes back in `use_case`, # and `draft` is archived with `superseded_by` naming it — one call, one # transaction, still exactly one current draft. Retrying with the same # idempotency_key returns the same successor rather than drafting another. refined = await client.use_cases.refine( draft["use_case_id"], workspace_id=workspace_id, description="Triage incoming refund requests and flag anything over $500 for review", idempotency_key=str(uuid.uuid4()), refinement_context=[{"note": "Also post high-value ones to Slack."}], ) current = refined["use_case"] # None if it asked a clarifying question published = await client.use_cases.publish(current["use_case_id"], workspace_id=workspace_id) # The persisted bundle behind it — asset rows with real editor targets, # the bound flow's steps, and any still-open connection gaps. bundle = await client.use_cases.get_bundle( current["use_case_id"], workspace_id=workspace_id ) # Approving a pending connection request from the other side: await client.access_requests.grant( access_request_id, workspace_id=workspace_id, secret_bindings={"api_key": "billing-crm-api-key"}, )

Using the CLI

# Generate and save the draft plan orqestractl use-cases generate ws-1 \ --description "Triage incoming refund requests and flag anything over $500 for review" \ --output draft-plan.json # Create it — accepts either the generate response or a bare bundle plan orqestractl use-cases create ws-1 \ --file draft-plan.json \ --source-description "Triage incoming refund requests and flag anything over $500 for review" # Refine it — one call that REPLACES the draft: a fresh successor is created # and this draft is archived with superseded_by naming it, in one transaction. # --idempotency-key is required; re-running with the same one returns the same # successor instead of drafting another. --refinement-note is repeatable. orqestractl use-cases refine ws-1 <use_case_id> \ --description "Triage incoming refund requests and flag anything over $500 for review" \ --refinement-note "Route anything from enterprise accounts straight to review" \ --idempotency-key "$(uuidgen)" # List, inspect, and drive the lifecycle orqestractl use-cases list ws-1 --status draft orqestractl use-cases show ws-1 <use_case_id> orqestractl use-cases bundle ws-1 <use_case_id> orqestractl use-cases publish ws-1 <use_case_id> orqestractl use-cases archive ws-1 <use_case_id> orqestractl use-cases reopen ws-1 <use_case_id> orqestractl use-cases activate ws-1 <use_case_id> # Approve a pending connection request from the platform-team side orqestractl access-requests grant ws-1 <access_request_id> \ --secret-binding api_key=billing-crm-api-key

Using the Portal

Start from Workloads → Create → Describe with Assistant. Describe what you want in the chat-style intake; if the description leaves something ambiguous you’re asked a short follow-up before a draft appears.

The review card shows a plain-language summary, a worked “try it” example, and a “Show me what you built” panel — expand it to see each piece of the bundle (new, reused, or needing access) and open any of them in its real editor. Refine regenerates the draft from new instructions and REPLACES it: the fresh draft takes over the page and the one you refined is archived, so you never accumulate half-finished drafts. Regenerating discards edits you’ve made in the editor, so you’re asked to confirm first. Publish is the terminal action — once clicked it can’t be interrupted mid-flight.

If publishing needs a connection you can’t create yourself, the use case moves to a pending state: the review card shows an amber “needs access” row and a pending-request count, and the page polls until your platform team resolves it. Once every request is granted, the use case activates on its own and “Try it” switches from the worked example to real execution.

An owner who leaves a draft unfinished sees a “resume your drafted use case” reminder on their home screen; a platform-team member who is the last approver on a pending use case sees an activation reminder there instead, with a one-click action to finish activating it.

Troubleshooting

ErrorLikely cause
200 on redacted generateThe response is intentionally a redacted preview; unresolved references are shown as needs_admin gaps rather than disclosed
422 on full-detail generate, generate-and-create, refine, or createThe generated bundle failed schema/business-rule validation or contained a workspace reference that could not be resolved
422 on redacted generate-and-create or refineThe chained route reached draft instantiation; the response is a value-free error rather than a needs_admin preview
422 on publish (“model policy…”)The bundle’s model policy reference is no longer approved or reachable
Use case stuck at pending_accessA connection request is still awaiting your platform team’s approval
409 on publish/archive/reopenThe use case isn’t in a status that allows that transition
409 on refineThe draft was already replaced or published — refine its successor
404 on any routeThe use case (or its id) doesn’t exist in the given workspace