# Agent recipes (/agent-recipes)

End-to-end Agent Key workflows you can copy, paste, and run. The CLI path is recommended when your runtime can execute shell commands; direct HTTP examples are included for custom clients and environments where the CLI is not available.



See [CLI](/cli) for installation, credential resolution, output flags, and exit codes. See [Conventions](/conventions) for shared direct HTTP rules.

> **Substitutions used below**
>
> * `$AK` — your Agent Key (`ak-...`)
> * `$BASE` — `https://portal.eprospera.com` in production, `https://staging-portal.eprospera.com` in staging
> * `$EPROSPERA_API_KEY` — the key the CLI reads when `--api-key` is not passed

For automation, prefer:

```bash
eprospera --json --yes <group> <command>
```

***

## Recipe 1 — RPN lookup → registry search → fetch entity [#recipe-1--rpn-lookup--registry-search--fetch-entity]

Resolve a free-text query to a single legal entity, then fetch its full record.

**Required scopes:** `agent:verify_rpn`, `agent:registry.search`, `agent:entity.read`
&#x2A;*Prerequisites:** Read-only Agent Key. Manifestation of Will is **not** required.
&#x2A;*Note:** `entity get` / `GET /api/v1/legal_entities/{id}` only returns entities created via the API (see [Agent Keys → Important Limitations](/agent-keys#important-limitations)).

### CLI [#cli]

```bash
export EPROSPERA_API_KEY="$AK"

# 1. If you have an RPN, confirm it exists and is active
eprospera --json entity verify 80000000000012

# 2. Search by RPN or name to get a legal-entity UUID
eprospera --json entity search 80000000000012
eprospera --json entity search "Acme Holdings"

# 3. Fetch the entity by id
eprospera --json entity get <id>
```

`entity verify` confirms existence and active status; it does not return the legal-entity UUID. Use `entity search` before `entity get`.

### Direct HTTP [#direct-http]

```bash
curl -s -X POST "$BASE/api/v1/verify_rpn" \
  -H "Authorization: Bearer $AK" \
  -H "Content-Type: application/json" \
  -d '{"rpn": "80000000000012"}'

curl -s -X POST "$BASE/api/v1/registries/legal_entities/search" \
  -H "Authorization: Bearer $AK" \
  -H "Content-Type: application/json" \
  -d '{"query": "Acme Holdings"}'

curl -s "$BASE/api/v1/legal_entities/<id>" \
  -H "Authorization: Bearer $AK"
```

**Watch for**

* `entity verify` returning `"not_found"` → the RPN string is malformed or unknown; do not retry.
* Search returning an empty `results` array → broaden the query, or split multi-word queries on whitespace.
* CLI exit code `5` / HTTP `404` on entity fetch → either the entity does not exist, or it was created outside the API and is invisible to Agent Keys.

***

## Recipe 2 — Fully automated LLC incorporation [#recipe-2--fully-automated-llc-incorporation]

Create an LLC application, pay it with a fully-discounting voucher, and pick up the resulting legal-entity record. Zero browser hops when the prerequisites are satisfied.

**Required scopes:** `agent:entity.application.create`, `agent:entity.application.pay`, `agent:entity.application.read`, `agent:entity.read`
&#x2A;*Prerequisites:**

* Active **Manifestation of Will** signed by the Agent Key owner.
* The **Agreement of Coexistence** for the relevant residency type (Resident or e-Resident LLC) must be **pre-accepted** during MoW signing. Without this, the create response includes `nextSteps.signature`, which requires a human browser session.
* A voucher code that fully covers the application invoice and is owned by the key owner.
* The owner is an active e-Resident or Resident.

Create `application.json`:

```json
{
  "applicationData": {
    "residencyType": "e-Resident",
    "entityType": "llc",
    "name": "Acme Robotics",
    "extension": "LLC",
    "principalOffice": {
      "country": "US",
      "line1": "100 Main St",
      "line2": null,
      "city": "Wilmington",
      "state": "DE",
      "postalCode": "19801"
    },
    "contactEmail": "owner@example.com",
    "registeredAgentProvider": "prospera_employment_solutions"
  }
}
```

### CLI [#cli-1]

```bash
export EPROSPERA_API_KEY="$AK"

# 1. Validate locally while preparing the JSON request
eprospera --json --dry-run application create --file application.json

# 2. Create the application
eprospera --json --yes application create --file application.json
# Capture data.id as APP_ID.
# If nextSteps.signature is non-null, stop and ask the owner to accept the AOC in a browser.

# 3. Apply the fully covering voucher
eprospera --json --yes application pay "$APP_ID" --voucher FOUNDER100

# 4. Poll until approval or terminal failure
eprospera --json application watch "$APP_ID" --timeout 30m
# Capture data.legalEntityId once statusId is Approved.

# 5. Fetch the resulting legal-entity record
eprospera --json entity get "$LEGAL_ENTITY_ID"
```

### Direct HTTP [#direct-http-1]

```bash
curl -s -X POST "$BASE/api/v1/legal_entity_applications" \
  -H "Authorization: Bearer $AK" \
  -H "Content-Type: application/json" \
  --data @application.json

curl -s -X POST "$BASE/api/v1/legal_entity_applications/<APP_ID>/pay/voucher" \
  -H "Authorization: Bearer $AK" \
  -H "Content-Type: application/json" \
  -d '{"voucherCode": "FOUNDER100"}'

curl -s "$BASE/api/v1/legal_entity_applications/<APP_ID>" \
  -H "Authorization: Bearer $AK"

curl -s "$BASE/api/v1/legal_entities/<LEGAL_ENTITY_ID>" \
  -H "Authorization: Bearer $AK"
```

**Terminal application states:** `Approved` (success — `data.legalEntityId` is populated) and `Rejected` (failure — inspect the application in the portal for review notes). CLI exit code `10` means the application or payment reached a terminal failure state.

**Watch for**

* CLI exit code `8` / HTTP `400` on create → schema validation failed; fix `application.json`.
* CLI exit code `6` / HTTP `409` on create → entity name collides with an existing entity of the same type; pick a new name.
* `nextSteps.signature` is non-null → the AOC was not pre-accepted; a browser signature is required.
* Voucher errors → voucher is missing, expired, redeemed, or under-funds the invoice.
* CLI exit code `4` / HTTP `403` → missing scope or revoked MoW.

***

## Recipe 3 — Resident-paid incorporation [#recipe-3--resident-paid-incorporation]

Agent Key hosted-checkout creation is temporarily disabled. For delegated flows, use the voucher recipe above, or create the application with the Agent Key and have the resident complete payment in the portal.

Standard API keys can still use `POST /api/v1/legal_entity_applications/{id}/checkout_session` for API-created applications. The current CLI command surface covers voucher payments, not hosted checkout creation.

***

## Recipe 4 — Read account holder profile [#recipe-4--read-account-holder-profile]

Fetch the human owner's identity, residency status, and ID-verification artifacts. Useful for KYC review, compliance summaries, or pre-filling forms on the agent owner's behalf.

**Required scopes:** `agent:person.details.read`, `agent:person.residency.read`, `agent:person.id_verification.read`
&#x2A;*Prerequisites:** Read-only Agent Key. MoW not required.

### CLI [#cli-2]

```bash
export EPROSPERA_API_KEY="$AK"

eprospera --json --fields id,fullName,email me profile
eprospera --json me residency
eprospera --json me id-verification
```

### Direct HTTP [#direct-http-2]

```bash
curl -s "$BASE/api/v1/me/natural-person" \
  -H "Authorization: Bearer $AK"

curl -s "$BASE/api/v1/me/natural-person/residency" \
  -H "Authorization: Bearer $AK"

curl -s "$BASE/api/v1/me/natural-person/id-verification" \
  -H "Authorization: Bearer $AK"
```

**Watch for**

* `/api/v1/me/natural-person` returning `null` → the owner has no approved residency yet.
* `/residency` returning `activeResidency: null` with `wasEverResident: true` → the owner is a former resident; treat as inactive.
* `/id-verification` returning all-`null` document URLs → the owner has not completed ID verification.
* These commands/endpoints accept OAuth tokens **and** Agent Keys — but **not** standard `sk-` keys.

***

## Polling guidance [#polling-guidance]

For CLI workflows, prefer:

```bash
eprospera --json application watch <application-id> --timeout 30m
```

For direct HTTP, poll `GET /api/v1/legal_entity_applications/{id}` every **30 seconds** for the first 2 minutes, then back off to every **5 minutes**. There are no webhooks today (see [Conventions → Webhooks](/conventions#webhooks)). `Approved` and `Rejected` are terminal — stop polling.

## Common errors quick-reference [#common-errors-quick-reference]

| CLI exit | HTTP status | Likely cause                                                                |
| -------- | ----------- | --------------------------------------------------------------------------- |
| `2`      | n/a         | Invalid command syntax or missing argument; inspect `eprospera schema`.     |
| `3`      | `401`       | Missing/invalid credential, or the Agent Key was revoked.                   |
| `4`      | `403`       | The Agent Key lacks a required scope, or the MoW was revoked.               |
| `5`      | `404`       | Resource does not exist or is invisible to your Agent Key.                  |
| `6`      | `409`       | Entity name conflict or impossible state transition.                        |
| `7`      | `429`       | Rate limit exceeded on `verify_rpn` / registry search.                      |
| `8`      | `400`       | Request body fails validation or a state precondition failed.               |
| `9`      | n/a         | Polling or network timeout; surface the last known state.                   |
| `10`     | n/a         | Application or voucher reached terminal failure.                            |
| `1`      | `500`       | Unexpected server or CLI failure; retry only idempotent reads with backoff. |
