# Curl

# curl Guide

Copy-paste-ready `curl` commands for every core Amdahl Platform API operation. Use this when you are exploring the API, wiring a shell script, or debugging a problem in another SDK and need to isolate whether the issue is transport or logic.

All examples assume:

```bash
export API_KEY="sk_live_your_key_here"
```

Base URL: `https://app.amdahl.co/api/platform/v1`.

Common flags you will see below:

| Flag                      | Meaning                                                                                 |
| ------------------------- | --------------------------------------------------------------------------------------- |
| `-sS`                     | Silent except on errors. Always use this for scripts.                                   |
| `-X METHOD`               | HTTP verb. `GET` is the default so most GET calls omit this.                            |
| `-H 'Name: value'`        | Set a header. Repeat for multiple headers.                                              |
| `-d '{...}'`              | JSON body. Combine with `-H "Content-Type: application/json"`.                          |
| `-d @file.json`           | Send a body loaded from a file.                                                         |
| `-G --data-urlencode k=v` | Send query parameters safely for GET requests.                                          |
| `-N`                      | Disable output buffering. Required for Server-Sent Events.                              |
| `-v`                      | Verbose. Prints request + response headers. Use for debugging auth or signature issues. |
| `-i`                      | Print response headers alongside the body.                                              |
| `--fail-with-body`        | Exit non-zero on 4xx/5xx but still print the body. Great for scripts.                   |

## Authentication

Every request needs the `Authorization: Bearer $API_KEY` header. See [authentication.md](../authentication.md) for key provisioning.

Sanity check:

```bash
curl -sS "https://app.amdahl.co/api/platform/v1/me" \
  -H "Authorization: Bearer $API_KEY"
```

Expected response: JSON with `business_id`, `scopes`, and `expires_at`. A `401` means the key is invalid or revoked.

## Pages

A Page is a workspace-authored data UI: a catalog-component spec plus named queries the host runs server-side. The CRUD verbs below map one-to-one onto `curl`.

### List pages

```bash
curl -sS "https://app.amdahl.co/api/platform/v1/pages" \
  -H "Authorization: Bearer $API_KEY"
```

### Get a page

```bash
curl -sS "https://app.amdahl.co/api/platform/v1/pages/$PAGE_ID" \
  -H "Authorization: Bearer $API_KEY"
```

### Create a page

`name` and `spec` are required. The spec is verified before it persists; a broken draft is rejected with a per-stage verdict. Requires `pages:write`.

```bash
curl -sS -X POST "https://app.amdahl.co/api/platform/v1/pages" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Weekly sentiment",
    "tags": ["weekly", "sentiment"],
    "declared_queries": [
      { "name": "by_channel", "sql": "SELECT channel, COUNT(*) AS events FROM interactions GROUP BY channel" }
    ],
    "spec": {
      "type": "Section",
      "children": [
        { "type": "Table", "data": { "$query": "by_channel" } }
      ]
    }
  }'
```

### Update a page

Patch the spec, declared queries, or metadata in place. Requires `pages:write`.

```bash
curl -sS -X PATCH "https://app.amdahl.co/api/platform/v1/pages/$PAGE_ID" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "tags": ["weekly", "sentiment", "approved"] }'
```

### Validate a page (dry run)

Check a spec without persisting it. Returns the same verdict the create path enforces. Requires `pages:read`.

```bash
curl -sS -X POST "https://app.amdahl.co/api/platform/v1/pages/validate" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Draft", "spec": { "type": "Section", "children": [] } }'
```

### Archive a page

```bash
curl -sS -X DELETE "https://app.amdahl.co/api/platform/v1/pages/$PAGE_ID" \
  -H "Authorization: Bearer $API_KEY"
```

Archive is reversible. The permanent hard delete is a separate `POST /pages/:id/hard-delete` (scope `pages:delete`).

## Agents

### Start an agent run

```bash
curl -sS -X POST "https://app.amdahl.co/api/platform/v1/agents/run" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "profile_id": "content_writer",
    "task": "Draft a 250-word LinkedIn post on our Q1 data-quality retrospective.",
    "input_params": { "channel": "linkedin", "content_type": "linkedin_post" },
    "async": true
  }'
```

### Poll agent status

```bash
curl -sS "https://app.amdahl.co/api/platform/v1/agents/$SESSION_ID/status" \
  -H "Authorization: Bearer $API_KEY"
```

### Resume a paused agent

```bash
curl -sS -X POST "https://app.amdahl.co/api/platform/v1/agents/$SESSION_ID/resume" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "input": { "approved": true } }'
```

### Stream progress (SSE)

`-N` disables output buffering so events print as they arrive. Run in a terminal; Ctrl-C to stop.

```bash
curl -sN "https://app.amdahl.co/api/platform/v1/agents/$SESSION_ID/stream" \
  -H "Authorization: Bearer $API_KEY"
```

Each event block looks like:

```
event: tool.completed
data: {"type":"tool.completed","data":{"tool":"knowledge_base.search","duration_ms":412}}
```

## Data

### Explore schema

```bash
curl -sS -X POST "https://app.amdahl.co/api/platform/v1/data/explore" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "scope": "tables" }'
```

### Query data

```bash
curl -sS -X POST "https://app.amdahl.co/api/platform/v1/data/query" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "sql": "SELECT channel, COUNT(*) FROM interactions WHERE occurred_at > now() - interval '\''7 days'\'' GROUP BY 1" }'
```

### Search the knowledge base

```bash
curl -sS -X POST "https://app.amdahl.co/api/platform/v1/data/search" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "query": "onboarding drop-off week 2", "limit": 10 }'
```

## Webhooks

### Register a webhook

```bash
curl -sS -X POST "https://app.amdahl.co/api/platform/v1/webhooks" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-tunnel.example.com/hooks/amdahl",
    "events": ["artifact.status_changed", "agent.session.completed"]
  }'
```

Save the `secret` from the response. It is shown once.

### List webhooks

```bash
curl -sS "https://app.amdahl.co/api/platform/v1/webhooks" \
  -H "Authorization: Bearer $API_KEY"
```

### Update a webhook

```bash
curl -sS -X PATCH "https://app.amdahl.co/api/platform/v1/webhooks/$WEBHOOK_ID" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true }'
```

### Fire a test delivery

```bash
curl -sS -X POST "https://app.amdahl.co/api/platform/v1/webhooks/$WEBHOOK_ID/test" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "artifact.status_changed",
    "payload": { "artifact_id": "art_test", "status": "saved", "previous_status": "draft", "artifact_type": "blog_post", "title": "Test" }
  }'
```

### Delete a webhook

```bash
curl -sS -X DELETE "https://app.amdahl.co/api/platform/v1/webhooks/$WEBHOOK_ID" \
  -H "Authorization: Bearer $API_KEY"
```

## Error handling

Parse both the HTTP status and the JSON error envelope. Every non-2xx response has this shape:

```json
{ "error": { "code": "invalid_argument", "message": "profile_id is required" } }
```

Script-safe pattern:

```bash
if ! body=$(curl -sS --fail-with-body \
  -X POST "https://app.amdahl.co/api/platform/v1/agents/run" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d "$payload"); then
  echo "request failed: $body" >&2
  exit 1
fi
echo "$body" | jq .
```

Full error code reference: [api-reference/errors.md](../api-reference/errors.md).

## Pagination

Cursor-paginated list endpoints return `next_cursor` (null when you are at the end). Pass it back as `?cursor=...`. The loop below works against any such endpoint; swap in the resource path and the array key it returns:

```bash
cursor=""
while : ; do
  resp=$(curl -sS -G "https://app.amdahl.co/api/platform/v1/<list-endpoint>" \
    -H "Authorization: Bearer $API_KEY" \
    --data-urlencode "limit=100" \
    ${cursor:+--data-urlencode "cursor=$cursor"})
  echo "$resp" | jq '.items[]? | .id'
  cursor=$(echo "$resp" | jq -r '.next_cursor // empty')
  [ -z "$cursor" ] && break
done
```

## Debugging tips

- **Always use `-sS`**, not plain `-s`. `-sS` suppresses the progress bar but still surfaces network errors.
- **Add `-v` when auth looks off**. The request headers in verbose output confirm your `Authorization` header is actually being sent.
- **Use `jq` to filter responses**: `curl ... | jq '.rows | length'` is faster than scrolling.
- **Pipe large bodies to a file**: `curl -sS ... > out.json` then inspect with `jq` or `less`. Avoids terminal rendering lag on big responses.
- **Save your base URL + key in `~/.curlrc-amdahl`**: `echo "-H \"Authorization: Bearer $API_KEY\"" > ~/.curlrc-amdahl` then `curl -K ~/.curlrc-amdahl ...`. Keeps secrets out of shell history.
- **Watch rate limits**: the response headers include `X-RateLimit-Remaining` and `X-RateLimit-Reset`. See [rate-limits.md](../rate-limits.md).

## See also

- [quickstart.md](../quickstart.md) to get your first call working end-to-end.
- [sdk/typescript.md](./typescript.md) for the Node.js equivalent of everything here.
- [sdk/python.md](./python.md) for the Python equivalent.
- [api-reference/README.md](../api-reference/README.md) for the full endpoint catalog.
- [pagination-errors.md](../pagination-errors.md) for the pagination and error model details.
