01 · Authentication
Organization-scoped machine identity.
Access tokens come from an Auth0 organization grant, target the gateway audience, expire in no more than ten minutes, and carry only explicitly granted scopes. Prefer private_key_jwt. Client secrets are an approved compatibility mode and rotate within 90 days.
curl --request POST 'https://programmers-union-agent-gateway.vercel.app/oauth/token' \
--header 'Content-Type: application/json' \
--data '{
"grant_type": "client_credentials",
"client_id": "'$PU_CLIENT_ID'",
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": "'$PU_CLIENT_ASSERTION'",
"audience": "https://programmers-union-agent-gateway.vercel.app",
"organization": "'$PU_AUTH0_ORGANIZATION'"
}'02 · Quickstart
Create one idempotent work order.
The request describes technical work and acceptance criteria. It never names a worker or supplies raw credentials. A successful intake is acknowledged with 202 Accepted.
curl --request POST 'https://programmers-union-agent-gateway.vercel.app/v1/work-orders' \
--header 'Authorization: Bearer $PU_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: wo_2026_09_15_001' \
--data '{
"kind": "SECURITY_HARDENING",
"summary": "Review an AI-built Next.js checkout",
"description": "Reproduce the reported failure, check authorization boundaries, and prepare a verified preview.",
"acceptanceCriteria": [
"Cross-organization access tests pass",
"No secrets appear in build artifacts",
"Protected Vercel preview is available"
],
"requestedDeadline": "2026-09-24T18:03:33.194Z",
"deliveryMode": "TEST",
"environment": "PREVIEW",
"riskFlags": { "securitySensitive": true }
}'HTTP/1.1 202 Accepted
X-Request-Id: req_5ee8…
{
"id": "cmg…",
"version": 1,
"status": "RECEIVED",
"statusUrl": "https://programmers-union-agent-gateway.vercel.app/v1/work-orders/cmg…",
"receivedAt": "2026-09-15T08:31:12.012Z",
"triageBy": "2026-09-15T08:46:12.012Z",
"confirmedDeliveryAt": null
}03 · Lifecycle
One state everywhere.
RECEIVED→TRIAGING→NEEDS_CLARIFICATION→AWAITING_QUOTE_APPROVAL→DISPATCH_PENDING→SCHEDULED→IN_PROGRESS→QA_REVIEW→TEST_READY→AWAITING_PRODUCTION_APPROVAL→DEPLOYING→COMPLETED
TRIAGING ↔ NEEDS_CLARIFICATION, IN_PROGRESS ↔ QA_REVIEW, and cancellation races are explicit. REJECTED, CANCELLED, and FAILED are terminal. Once work has begun, cancellation becomes CANCELLATION_REQUESTED until a human resolves scope and refund handling.
The response’s actionRequired is one of NONE, PROVIDE_CLARIFICATION, HUMAN_QUOTE_APPROVAL, or HUMAN_PRODUCTION_APPROVAL.
04 · Deadlines
Three timestamps, three meanings.
requestedDeadlineThe agent’s requested outcome time. It is not a promise.
triageBySubmission +15 minutes when the full interval fits staffed hours; otherwise next staffed opening +15 minutes.
confirmedDeliveryAtPublished only after Cliviti reserves capacity and a human PU dispatcher approves the assignee.
05 · Events
Resume from a cursor.
Poll GET /work-orders/{id}/events?after=42. Events are ordered, public-safe, and carry a monotonically increasing sequence. CLI follow mode emits one JSON object per line.
pu work events cmg… --follow --jsonl
{"sequence":2,"type":"TRIAGE_STARTED","status":"TRIAGING"}
{"sequence":3,"type":"QUOTE_PUBLISHED","status":"AWAITING_QUOTE_APPROVAL"}06 · Errors and retries
Stable problem codes.
Errors use application/problem+json. Treat HTTP status as transport meaning, code as machine logic, and retryable as retry guidance.
{
"type": "https://programmersunion.org/problems/idempotency-conflict",
"title": "Idempotency conflict",
"status": 409,
"detail": "This key was already used with a different request.",
"code": "IDEMPOTENCY_CONFLICT",
"requestId": "req_…",
"retryable": false
}Every mutation uses Idempotency-Key. An identical replay returns the stored response for seven days. Reusing the key with a changed body returns 409 IDEMPOTENCY_CONFLICT.
07 · REST
Small surface, narrow scopes.
| Method | Path | Scope |
|---|---|---|
GET | /capabilities | Public |
POST | /availability-checks | availability:read |
POST | /work-orders | work_orders:create |
GET | /work-orders[/{id}] | work_orders:read |
GET | /work-orders/{id}/events | work_orders:read |
POST | /work-orders/{id}/messages | work_orders:message |
POST | /work-orders/{id}/cancel-requests | work_orders:cancel |
There are no agent scopes for quote approval, payment, worker assignment, payroll, contact disclosure, repository approval, or production deployment.
08 · MCP
Six tools, no extra authority.
check_availabilityavailability:readrequest_human_taskwork_orders:createget_work_orderwork_orders:readget_work_order_eventswork_orders:readadd_work_order_inputwork_orders:messagecancel_work_orderwork_orders:cancelThe remote MCP server is a thin adapter over REST and receives the same ten-minute token. A2A is deliberately deferred in V1.
09 · CLI
Designed for scripts and humans.
pu auth login
pu capabilities list --json
pu work create --file ./work-order.json --json
pu work status cmg… --json
pu work events cmg… --follow --jsonl
pu work message cmg… --file ./clarification.json --json
pu work cancel cmg… --reason "Customer changed scope"Credentials are stored in the operating-system keychain. JSON output is stable; diagnostics go to stderr.
10 · Webhooks
Registered by humans, signed by the gateway.
Endpoints are created only in the authenticated portal. The signature covers the timestamp, event ID, and raw body. Consumers reject messages older than five minutes and deduplicate by event ID. Delivery retries at 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, and 24 hours before dead-lettering.
X-PU-Event-Id: evt_…
X-PU-Timestamp: 1789459272
X-PU-Signature: v1=<HMAC_SHA256(timestamp + "." + eventId + "." + rawBody)>11 · Security boundary
Assume every artifact is hostile.
Task text, code, dependencies, build artifacts, and external URLs are untrusted. Human work runs in isolated environments with malware, secret, and dependency scanning. Repository grants are human-approved and repository-scoped; access is revoked at closure. A separate release runner owns deployment credentials.
- Workers, payroll, private calendars, and contact details remain private.
- Payment occurs through a human-approved secure checkout in the portal.
- FINAL delivery must produce and pass a preview before production approval.
- Customer and PU release-manager approvals bind to the exact commit, build, evidence, rollback plan, and environment.
- Any material change expires prior production approvals.
Next
