# FinancialFilings API: key for AI agents

An AI agent can create an API key in one call. No browser, no email code.

## 1. Sign up (no auth)

    POST https://api.financialreports.eu/agent/signup
    Content-Type: application/json

    {"email": "<your user's real work email>", "agent_name": "<your name, 1-64 chars: letters, digits, space, _ or ->"}

`201` returns `api_key` **once**. Store it. Send it as `X-API-Key` on every call.
Use the email of the person you work for; they own the account. Never use someone else's address.
If the prompt your user gave you has a hand-off token, add it to the same body as `"handoff": "<token>"`. It is optional.

- `409 account_exists`: the address cannot get a new account, usually because it already has one. The body also has `claim_token`, `user_code` and `claim_endpoint`. Show your user the `user_code`: if they have an account, FinancialFilings emails them a link; they sign in from it and enter the code. Meanwhile `POST https://api.financialreports.eu/agent/key-claim` with `{"claim_token": "<claim_token>"}` at most every 5 seconds: `202` means still waiting, `200` returns their account's `api_key` once (it replaces any key they had, which they are warned about), `410` means expired (after 24 hours), already collected or refused. If you sign up again for the same address, switch to the new `claim_token` and show the new code (at most one email per address per 24 hours; the owner can approve with the newest code). If the `200` response is lost, the key cannot be shown again: ask your user to roll it from the dashboard. If no email arrives, ask your user for a key from https://financialfilings.com/accounts/api-dashboard/ .
- `400`: bad email (reserved, disposable) or bad `agent_name`.
- `429` / `503`: wait `retry_after_seconds`. Do not loop.

Example `201` body (your values differ):

    {
      "api_key": "<your new key, shown once>",
      "key_last4": "<last 4 characters of the key>",
      "email": "<the email you sent>",
      "agent_name": "<the agent_name you sent>",
      "status": "sandbox",
      "sandbox": {
        "requests_remaining": 25,
        "expires_at": "<UTC time 72 hours after signup, e.g. 2026-01-31T09:30:00Z>",
        "scope": "Level 1 read-only (GET) endpoints"
      },
      "auth_header": "X-API-Key",
      "message": "This key works now for 25 Level-1 GET requests within 72 hours. Store the key now; it is shown once. Next step, now: POST /agent/owner-confirmation so the owner of this address gets a one-click confirmation email (free tier), and tell your user to look for it. The trial keeps working meanwhile. Alternatively, POST /agent/checkout-link and give the returned URL to your user to add a card (pay-as-you-go, Levels 1-3).",
      "owner_confirmation_endpoint": "https://api.financialreports.eu/agent/owner-confirmation",
      "status_endpoint": "https://api.financialreports.eu/agent/status",
      "docs_url": "https://api.financialreports.eu/agent/",
      "checkout_link_endpoint": "https://api.financialreports.eu/agent/checkout-link"
    }

If no trial is available, `status` is `"unfunded"` and `sandbox` is `null` (step 3).

## 2. Ask your user to confirm (do this right away)

    POST https://api.financialreports.eu/agent/owner-confirmation
    X-API-Key: <key>

We email your user a one-click confirmation link. When they click Confirm, the key gets the free tier (Level 1, monthly allowance) and stays the same key. Tell them to look for the email; if you have a sandbox, it keeps working while they do. Until they confirm, use the key from one machine: if it is used from more than 3 networks first, the confirmation link stops working and the key can only be unlocked with a card. Do this now, not when the sandbox runs out: if you finish inside the sandbox, your user otherwise never learns the key exists. At most one email per address per 24 hours. If a `402` body has no `owner_confirmation_endpoint`, this step is not available for that key: it can only be unlocked with a card (the multi-network rule in step 3).

## 3. Use the sandbox

A new key can make 25 Level-1 GET requests within 72 hours (company and filing metadata). The latest filings for one company take two calls. First find the company (results are ranked by relevance; each has an `id` and its ISINs):

    GET https://api.financialreports.eu/companies/?search=siemens&page_size=5
    X-API-Key: <key>

Then list its filings, newest first:

    GET https://api.financialreports.eu/filings/?company=<id>&ordering=-release_datetime&page_size=10
    X-API-Key: <key>

If you already know an ISIN, skip the search: `https://api.financialreports.eu/filings/?company_isin=DE0007236101&ordering=-release_datetime&page_size=10`. `/filings/?search=siemens` also works, but it matches titles and company names across every company (Siemens Energy, Siemens Healthineers, ...); `company` or `company_isin` pins one issuer. Always filter list calls (`company`, `company_isin`, `lei`, `countries=DE`, ...): an unfiltered `/filings/` can time out. All parameters: https://api.financialreports.eu/docs/ .

The `X-Agent-Sandbox-Remaining` response header counts down; every call above uses one request.

A key can make up to 120 requests a minute, so parallel lookups are fine. If you go faster, a `429` gives `retry_after_seconds`, and a refused call does not use up a trial request.

If the signup response has `"sandbox": null`, no trial is available for this signup right now (trials are limited per day). That is expected, not an error: data calls wait for step 2. Once your user confirms, the same key works.

A trial key is for testing from one machine. If it is used from more than 3 networks (proxy rotation, a distributed crawler), the trial stops and the key can only be unlocked with a card (step 4, pay-as-you-go).

## 4. Get the key activated

Beyond the sandbox, data calls return **`402 payment_required`**. The body lists what unlocks the key:

- **Owner confirmation (free tier).** Step 2. If you have not sent it yet, `POST https://api.financialreports.eu/agent/owner-confirmation` with your key now.
- **Add a card (pay-as-you-go, Levels 1-3).** `POST https://api.financialreports.eu/agent/checkout-link` with your key returns a `checkout_url` (valid about 23 hours). Give it to your user directly. After they add a card, the key switches to pay-as-you-go within seconds. Until the owner confirms the email, spend is capped at $10/day and $50/month.

Check progress with `GET https://api.financialreports.eu/agent/status` (at most once every 5 seconds; stop after 10 minutes and ask your user).

## Rules

- Never post the API key or a checkout URL in a shared channel, log or public repository.
- Rotate a leaked key with `POST https://api.financialreports.eu/agent/key/rotate` (needs the current key).
- If your user signs in to the website before confirming, the key you hold is replaced; ask them for the new one.

Full API reference: https://api.financialreports.eu/docs/

