Skip to content

Curl Agent

The curl agent is the universal HTTP connector. It performs arbitrary HTTP requests — fetching data from URLs (sources) or delivering workspace files to endpoints (targets). No credentials or API keys are required; use it for public APIs, webhooks, health checks, or any HTTP call that doesn’t need a dedicated connector.

The agent infers direction from your YAML: sources trigger GET requests (downloading data), while target_entries trigger POST requests (uploading data). There is no action field — the presence of sources vs. targets is all that’s needed. Requests are retried up to 3 times with exponential backoff on transient errors (429, 500, 503). JSON responses are automatically pretty-printed.


- name: fetch-api
agent: curl
sources:
- name: response.json
url: "https://api.example.com/data"
headers:
Authorization: "Bearer $(inputs.token)"

The curl agent uses phase:standard capability. Unlike most connector agents, it has no action field — direction is inferred from whether you specify sources, target_entries, or both.

FieldTypeRequiredDescription
namestringYesUnique phase name within the workflow
typestringNoDefaults to "standard"
agentstringYesMust be "curl"
depends_onstring[]NoUpstream phases that must complete before this phase runs
sourcesSourceEntry[]Required unless target_entriesURLs to fetch content from
target_entriesTargetEntry[]Required unless sourcesURLs to deliver content to
FieldTypeRequiredDescription
namestringYesOutput filename written to .cliq/files/{phase}/
urlstringYesURL to fetch
methodstringNoHTTP method (default: GET, or POST when body is present)
headersobjectNoRequest headers as key-value pairs
bodystringNoRequest body string. When present, method defaults to POST and Content-Type defaults to application/json
FieldTypeRequiredDescription
namestringYesIdentifier for the delivery
urlstringYesDestination URL
filestringYesWorkspace file to send as request body
methodstringNoHTTP method (default: POST)
headersobjectNoRequest headers; Content-Type is inferred from file extension if not set
modestringNoBody encoding: "json" (default) or "form"

No agent-specific settings required. The curl agent works out of the box with no configuration.


{
"data": {
"sources": {
"api-response": {
"url": "https://api.example.com/data",
"method": "GET",
"status": 200,
"size": 1024,
"content_type": "application/json",
"file": ".cliq/files/fetch-data/api-response"
}
},
"targets": {
"webhook": {
"url": "https://hooks.example.com/ingest",
"method": "POST",
"status": 200,
"size": 42
}
}
},
"text": "## Curl Results\n\n✓ Fetched api-response — GET https://api.example.com/data → 200 (1024 bytes)\n✓ Delivered webhook — POST https://hooks.example.com/ingest → 200 (42 bytes)"
}
FieldLocationDescription
urldata.sources.*, data.targets.*The request URL
methoddata.sources.*, data.targets.*HTTP method used (GET, POST, etc.)
statusdata.sources.*, data.targets.*HTTP response status code
sizedata.sources.*, data.targets.*Response/request body size in bytes
content_typedata.sources.*Response Content-Type header
filedata.sources.*Local path to the fetched content: .cliq/files/{phase}/{name}

Source responses are saved to .cliq/files/{phase}/{source.name}. JSON responses are pretty-printed automatically.

The file field tells downstream phases where the fetched content lives on disk. Reference it (and other handoff fields) using template variables:

commands:
- name: check
run: 'cat $(handoff.fetch-data.sources.api-response.file)'
- name: verify-status
run: 'test $(handoff.fetch-data.sources.api-response.status) -eq 200'

Example: Fetch an OpenAPI spec and generate code

Section titled “Example: Fetch an OpenAPI spec and generate code”

Pull a public API specification, then hand off to a coding agent to generate a client.

phases:
- name: fetch-spec
agent: curl
sources:
- name: openapi.json
url: https://petstore3.swagger.io/api/v3/openapi.json
- name: generate-client
agent: cursor
role: developer
depends_on: [fetch-spec]

Verify a staging service is healthy before proceeding with a deploy phase.

phases:
- name: health-check
agent: curl
sources:
- name: status.json
url: https://staging.example.com/healthz
headers:
Accept: application/json
- name: deploy
agent: exec
depends_on: [health-check]
commands:
- name: deploy
run: ./scripts/deploy.sh

Query a GraphQL endpoint using a request body — method defaults to POST when body is present.

phases:
- name: query-users
agent: curl
sources:
- name: users.json
url: https://api.example.com/graphql
body: '{ "query": "{ users { id name email } }" }'
headers:
Authorization: "Bearer ${GQL_TOKEN}"
- name: process
agent: cursor
role: analyst
depends_on: [query-users]

Post a generated report to an external webhook endpoint after a previous phase creates it.

phases:
- name: generate-report
agent: cursor
role: analyst
- name: deliver
agent: curl
depends_on: [generate-report]
target_entries:
- name: report
file: report.json
url: https://hooks.example.com/reports
method: PUT
headers:
Content-Type: application/json
X-API-Key: "${WEBHOOK_KEY}"

No setup required. The curl agent has no external dependencies, credentials, or environment variables.

Terminal window
cliq doctor agent curl

This always passes — the agent is ready to use immediately.