API version 2026-09-15 · invite-only pilot

Agent protocol, not extra authority.

REST is the canonical contract. MCP and pu are thin clients over the same organization, scope, payment, and approval boundaries.

Pilot access required. These examples document the contract but are not currently callable. Machine intake is disabled for this release; approved pilot operators must sign in through Vercel SSO, and organization credentials are not being issued yet.

Configured gateway base
https://programmers-union-agent-gateway.vercel.app/v1
Isolation boundary
Separate SSO-protected origin
MCP transport
https://programmers-union-agent-gateway.vercel.app/mcp
Availability
Mon–Sat · 09:00–21:00 IST

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.

Request an access tokenshell
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.

Create a work ordershell
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 }
  }'
Durable acknowledgementhttp
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.

  1. RECEIVED
  2. TRIAGING
  3. NEEDS_CLARIFICATION
  4. AWAITING_QUOTE_APPROVAL
  5. DISPATCH_PENDING
  6. SCHEDULED
  7. IN_PROGRESS
  8. QA_REVIEW
  9. TEST_READY
  10. AWAITING_PRODUCTION_APPROVAL
  11. DEPLOYING
  12. 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.

requestedDeadline

The agent’s requested outcome time. It is not a promise.

triageBy

Submission +15 minutes when the full interval fits staffed hours; otherwise next staffed opening +15 minutes.

confirmedDeliveryAt

Published 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.

Follow public eventsshell
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.

Changed-body idempotency conflictjson
{
  "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.

MethodPathScope
GET/capabilitiesPublic
POST/availability-checksavailability:read
POST/work-orderswork_orders:create
GET/work-orders[/{id}]work_orders:read
GET/work-orders/{id}/eventswork_orders:read
POST/work-orders/{id}/messageswork_orders:message
POST/work-orders/{id}/cancel-requestswork_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:read
request_human_taskwork_orders:create
get_work_orderwork_orders:read
get_work_order_eventswork_orders:read
add_work_order_inputwork_orders:message
cancel_work_orderwork_orders:cancel

The 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 CLIshell
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.

Verify the signed envelopehttp
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

Test the contract in a credential-isolated sandbox.

Agent Gateway Protocol & API Documentation | Programmers' Union