CUA API Reference

Computer Use Agent (CUA) — human-in-the-loop browser automation for EU government portals. Start sessions, stream real-time actions, confirm or rollback steps.

Overview

The CUA API enables automated interaction with EU government portals (e.g., TED, Simap, national procurement platforms) through a supervised browser agent. Every action requires human confirmation before execution, ensuring full auditability and control.

Base URL

https://staging.pauhu.eu

The base URL is configurable via the VITE_CUA_API environment variable in client applications.

Workflow

  1. Start a session targeting a specific portal and task.
  2. Stream real-time events via Server-Sent Events (SSE).
  3. Confirm or reject each pending action before it executes.
  4. Rollback to a previous step if needed.
  5. Stop the session when the task is complete or abandoned.

Authentication

All endpoints require authentication. The CUA API supports the same authentication methods as the main Pauhu API:

MethodHeaderExample
JWT (EdDSA) Authorization: Bearer <token> Issued by the Pauhu auth endpoint
API Key Authorization: Bearer pk_* Generated from the API Keys dashboard

The free tier (3 requests/day) applies. Higher tiers unlock additional session concurrency and action throughput.

POST /v1/cua/start

Start a new CUA session targeting a government portal.

Request body

FieldTypeRequiredDescription
portalstringYesTarget portal domain (must be allowlisted)
taskstringYesHuman-readable description of the task
urlstringNoStarting URL within the portal

Example request

curl -X POST https://staging.pauhu.eu/v1/cua/start \
  -H "Authorization: Bearer pk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "portal": "ted.europa.eu",
    "task": "Fill procurement notice form CN-2024-12345",
    "url": "https://ted.europa.eu/en/notice/-/detail/123456"
  }'

Example response

{
  "session_id": "cua_abc123",
  "status": "running",
  "portal": "ted.europa.eu",
  "stream_url": "/v1/cua/stream?session=cua_abc123"
}
FieldTypeDescription
session_idstringUnique session identifier (prefixed cua_)
statusstringSession status: running
portalstringConfirmed target portal
stream_urlstringRelative URL for the SSE event stream

POST /v1/cua/action

Manually trigger a CUA action within a running session.

Request body

FieldTypeRequiredDescription
session_idstringYesSession identifier
typestringYesAction type (see below)
targetstringNoCSS selector of the target element
descriptionstringNoHuman-readable description of the action
coordinatesobjectNo{ "x": number, "y": number } — viewport coordinates
valuestring | nullNoValue for type and select actions

Action types

TypeDescription
clickClick on an element or coordinates
typeType text into an input field
scrollScroll the viewport
navigateNavigate to a URL
selectSelect an option from a dropdown
submitSubmit a form
waitWait for a condition or timeout

Example request

curl -X POST https://staging.pauhu.eu/v1/cua/action \
  -H "Authorization: Bearer pk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "cua_abc123",
    "type": "click",
    "target": "#submit-button",
    "description": "Click the submit button",
    "coordinates": { "x": 450, "y": 320 },
    "value": null
  }'

POST /v1/cua/screenshot

Upload a viewport screenshot for the current session. Uses multipart/form-data encoding.

Request fields

FieldTypeRequiredDescription
session_idstringYesSession identifier
screenshotfileYesPNG image, max 5 MB

Example request

curl -X POST https://staging.pauhu.eu/v1/cua/screenshot \
  -H "Authorization: Bearer pk_your_api_key" \
  -F "session_id=cua_abc123" \
  -F "screenshot=@viewport.png"

Example response

{
  "screenshotUrl": "https://..."
}

GET /v1/cua/stream

Subscribe to a Server-Sent Events (SSE) stream for real-time session updates.

Query parameters

ParameterTypeRequiredDescription
sessionstringYesSession identifier

Example (curl)

curl -N "https://staging.pauhu.eu/v1/cua/stream?session=cua_abc123" \
  -H "Authorization: Bearer pk_your_api_key" \
  -H "Accept: text/event-stream"

Event types

EventDescription
action_pendingAn action is awaiting human confirmation
action_executingAn approved action is being performed
action_completedAn action finished successfully
action_failedAn action failed (includes error message)
session_updateSession status changed
form_confirmationForm fields are ready for human review
screenshotA new screenshot is available

Event payload

{
  "type": "action_pending",
  "sessionId": "cua_abc123",
  "action": {
    "id": "act_001",
    "type": "click",
    "status": "pending",
    "target": "#procurement-type",
    "description": "Select procurement type",
    "coordinates": { "x": 200, "y": 150 },
    "screenshotUrl": "https://...",
    "timestamp": "2026-03-11T10:00:00Z"
  }
}

JavaScript example

const source = new EventSource(
  'https://staging.pauhu.eu/v1/cua/stream?session=cua_abc123',
  // Note: EventSource does not support custom headers natively.
  // Use a library like eventsource-polyfill or fetch-event-source
  // to pass Authorization headers.
);

source.addEventListener('action_pending', (event) => {
  const data = JSON.parse(event.data);
  console.log('Action pending:', data.action.description);
  // Show confirmation UI to the user
});

source.addEventListener('action_completed', (event) => {
  const data = JSON.parse(event.data);
  console.log('Action completed:', data.action.id);
});

source.addEventListener('action_failed', (event) => {
  const data = JSON.parse(event.data);
  console.error('Action failed:', data.action.id, data.action.error);
});

source.addEventListener('screenshot', (event) => {
  const data = JSON.parse(event.data);
  document.getElementById('viewport').src = data.screenshotUrl;
});

source.addEventListener('form_confirmation', (event) => {
  const data = JSON.parse(event.data);
  console.log('Form ready for review:', data.fields);
});

source.onerror = () => {
  console.error('SSE connection lost, reconnecting...');
};

POST /v1/cua/confirm

Confirm or reject a pending action. Every action must be explicitly approved before it executes.

Request body

FieldTypeRequiredDescription
session_idstringYesSession identifier
action_idstringYesAction identifier from the action_pending event
approvedbooleanYestrue to execute, false to reject
editsobjectNoField overrides before execution (e.g., correcting a value)

Example — approve an action

curl -X POST https://staging.pauhu.eu/v1/cua/confirm \
  -H "Authorization: Bearer pk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "cua_abc123",
    "action_id": "act_001",
    "approved": true
  }'

Example — approve with edits

curl -X POST https://staging.pauhu.eu/v1/cua/confirm \
  -H "Authorization: Bearer pk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "cua_abc123",
    "action_id": "act_001",
    "approved": true,
    "edits": { "procurement_type": "open_procedure" }
  }'

Example — reject an action

curl -X POST https://staging.pauhu.eu/v1/cua/confirm \
  -H "Authorization: Bearer pk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "cua_abc123",
    "action_id": "act_001",
    "approved": false
  }'

POST /v1/cua/rollback

Rollback a session to a previous step. All actions after the target step are undone.

Request body

FieldTypeRequiredDescription
session_idstringYesSession identifier
to_stepintegerYesStep number to rollback to (1-based)

Example request

curl -X POST https://staging.pauhu.eu/v1/cua/rollback \
  -H "Authorization: Bearer pk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "cua_abc123",
    "to_step": 3
  }'

POST /v1/cua/stop

Stop a running CUA session. The session will be terminated and resources released.

Request body

FieldTypeRequiredDescription
session_idstringYesSession identifier

Example request

curl -X POST https://staging.pauhu.eu/v1/cua/stop \
  -H "Authorization: Bearer pk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "cua_abc123"
  }'

GET /v1/cua/stats

Retrieve dashboard statistics for CUA portal activity.

Example request

curl https://staging.pauhu.eu/v1/cua/stats \
  -H "Authorization: Bearer pk_your_api_key"

Example response

{
  "portals": [
    {
      "portal": "ted.europa.eu",
      "activeSessions": 2,
      "totalActions": 145,
      "successRate": 94.5,
      "lastActivity": "2026-03-11T10:30:00Z"
    }
  ]
}
FieldTypeDescription
portalstringPortal domain
activeSessionsintegerCurrently running sessions
totalActionsintegerTotal actions performed
successRatenumberSuccess percentage (0–100)
lastActivitystringISO 8601 timestamp of last activity

Error Codes

StatusCodeDescription
400Bad RequestInvalid or missing request fields
401UnauthorizedMissing or invalid authentication credentials
403ForbiddenPortal is not on the allowlist
404Not FoundSession not found or expired
409ConflictAction conflict (e.g., confirming an already-executed action)
413Payload Too LargeScreenshot exceeds 5 MB limit
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server error

Error response shape

{
  "error": {
    "code": 403,
    "message": "Portal not allowlisted: example.com",
    "request_id": "req_abc123"
  }
}

Support

Technical: support@pauhu.eu

Sales: sales@pauhu.eu