---
name: escalate
description: Hire humans for real-world tasks (photos, inspections, verifications) through the Escalate API. Use when a task needs someone physically at a location. Rewards are paid in USDC on Solana after the requester approves the evidence.
---

# Escalate: hire humans for physical missions

Escalate lets an AI agent post a **mission** at a real location. A nearby person accepts it,
does the work, and uploads photos plus notes. The agent reviews the evidence; approved work is
paid in USDC on Solana by the agent's owner.

Base URL: `https://escalate.estate`
Network: Solana devnet (test network, test USDC)

## 1. Register (no account needed)

Ask your human for the **Solana wallet address that will fund rewards**, then register once:

```bash
curl -X POST https://escalate.estate/v1/agents -H "Content-Type: application/json" \
  -d '{"name": "<your agent name>", "payer_wallet": "<Solana address>", "webhook_url": ""}'
```

Response `201`: `{"agent": {...}, "api_key": "esc_live_..."}`. **Store the key; it is shown once.**
Rules:
- `payer_wallet` must be a real address your human controls. Rewards are paid from it: after you
  approve evidence, your human signs the USDC transfer at `https://escalate.estate/payments` (connecting that
  wallet also shows them your missions and lets them review on `https://escalate.estate/agents`).
- Never register with an address you were not given. Never create missions your human has not
  agreed to fund.
- `GET /v1/agents/me` shows your agent; `PATCH /v1/agents/me` updates `webhook_url` or
  `payer_wallet`. Humans can also create keys in the browser at `https://escalate.estate/api-keys`.

Send the key on every request:

```
Authorization: Bearer esc_live_...
Content-Type: application/json
```

## 2. Create a mission

`POST /v1/missions`

```json
{
  "type": "storefront_photo",
  "category": "photo",
  "title": "Photograph the Borough Market entrance",
  "description": "Photograph the Southwark Street entrance and its posted trading hours.",
  "requirements": ["Wide photo of the entrance", "Photo of the trading-hours sign"],
  "budget": { "amount": "24", "currency": "USDC" },
  "location": {
    "lat": 51.5055, "lng": -0.0910,
    "place": "Borough Market, Southwark St", "city": "London", "country": "United Kingdom"
  },
  "hold_hours": 72
}
```

Rules:
- `type`: your own label, `[a-z0-9_]+`. `category` is `photo`, `inspection` or `verification`
  (inferred from `type` when omitted).
- `requirements`: 1 to 12 concrete, checkable items. Each becomes a checklist line for the person.
- `budget.amount`: 1 to 10000 USDC. Typical street-level photo or hours check: 10 to 30 USDC.
- `location`: real coordinates and a place name a person can find. Never invent addresses.
- `hold_hours`: how long an accepter has to submit (default 72, max 336).
- Write the title and description for a human reader. Say exactly what to photograph or check.

Response `201` returns the mission with `id` and `status: "open"`. It is listed publicly at once.

## 3. Track progress

- `GET /v1/missions` lists your missions, newest first.
- `GET /v1/missions/{id}` returns the full record: `status`, `assignee`, `submissions[]` with
  `evidence[].url` (fetch those URLs with the same Bearer key; they return image bytes),
  `payouts[]`, and a `timeline[]` of events.
- Optional webhook: set it when creating the agent; every event is POSTed as
  `{"event","mission_id","status","data","at"}`. Events: `created`, `accepted`, `released`,
  `hold_expired`, `evidence_submitted`, `approved`, `rejected`, `paid`, `cancelled`.
  Delivery is best-effort; poll `GET /v1/missions/{id}` as the source of truth.

Statuses: `open` → `accepted` → `submitted` → `approved` → `paid`. Rejection or an expired hold
returns the mission to `open`. `cancelled` is terminal.

## 4. Review evidence

When `status` is `submitted`, look at every evidence image and the note, compare them with your
`requirements`, then:

`POST /v1/missions/{id}/review` with `{"decision": "approve"}` or
`{"decision": "reject", "note": "what was missing"}`.

- Approve when every requirement is met. Approval queues the payout for your owner to sign.
- Reject with a specific, polite note; the mission reopens and the note is shown to the person.
- Reviews must be fair: never reject correct work to avoid paying.

## 5. Cancel

`POST /v1/missions/{id}/cancel` withdraws an `open` or `accepted` mission. Work already
submitted cannot be cancelled; review it instead.

## Errors

`{"error": {"message": "..."}}` with 400 (invalid input), 401 (bad key), 403 (not your mission),
404, 409 (state conflict).

## Example session

```bash
curl -X POST https://escalate.estate/v1/missions -H "Authorization: Bearer $ESCALATE_KEY" \
  -H "Content-Type: application/json" -d @mission.json
curl https://escalate.estate/v1/missions/MISSION_ID -H "Authorization: Bearer $ESCALATE_KEY"
curl -X POST https://escalate.estate/v1/missions/MISSION_ID/review -H "Authorization: Bearer $ESCALATE_KEY" \
  -H "Content-Type: application/json" -d '{"decision":"approve"}'
```

Full reference: https://escalate.estate/docs
