# Submit from a client SDK

> The one URL the client SDKs and every first-party proxy post to: an identification, or the deferred report that follows it, told apart by the body.

Last updated: 2026-09-29

```http
POST /api/v1/ingest
```

Authentication: Public key (`x-api-key: fly_pk_…`)

The browser SDK posts both of its calls here: the identification, and the deferred report after it. A [first-party proxy](https://docs.fingerly.io/docs/proxy-integrations) forwards everything it receives to this one URL without looking inside. Having one URL is what lets the SDK post to your proxy's path exactly as given, with nothing appended that a content blocker could match across sites. The iOS and Android SDKs, and the React Native, Flutter and Lynx packages over them, post their identifications here too, at `/api/v1/ingest` under the API origin they are configured with.

> **Note:** The client SDKs and every Fingerly proxy call this for you. `POST /identify` and `POST /events/{request_id}/supplement` remain for direct callers.

## Telling the two apart

| Body | Handled as | Answer |
| --- | --- | --- |
| Has a `token` | A [deferred report](https://docs.fingerly.io/reference/deferred-report). The request it belongs to comes from the signed token. | `202` with `request_id`, and `duplicate` when this exact report was already accepted. |
| No `token` | An [identification](https://docs.fingerly.io/reference/identify). | `200` with the complete verdict, exactly as `POST /identify` answers. |

**Headers**

- `x-api-key` (string, required): A public key, or a secret key from a server.
- `Idempotency-Key` (string): On an identification, up to 255 characters. Makes retries safe. See [Idempotency](https://docs.fingerly.io/reference/idempotency).
- `Content-Encoding` (string): `gzip` to send a compressed body.

**Body**

- `sdk` (object, required): The SDK's `platform` and `version`.
- `consent` (string, required): The consent state the SDK collected under. Must be `granted`; anything else, or no value, is refused with `422` `consent_required`. See [privacy and consent](https://docs.fingerly.io/docs/privacy-and-consent#consent).
- `signals` (object, required): The signal report the SDK collected. Produced by the SDKs and not a public contract.
- `tag` (string): On an identification, your own reference, echoed on the event and in webhooks.
- `token` (string): On a deferred report, the `deferred_token` from the identification's answer.

## Responses

The [identify response](https://docs.fingerly.io/reference/identify#response) and its headers, or the [deferred report response](https://docs.fingerly.io/reference/deferred-report#response). Errors are those of the matching endpoint, with `422` `invalid_supplement` for a token that is not valid, and `422` `consent_required` for either kind of body without `consent` `granted`.

A request forwarded by a proxy, or sent to a [hosted subdomain](https://docs.fingerly.io/docs/hosted-subdomain), is answered without `Fingerly-Balance-Micros`. A request that carries forwarded visitor headers without a proxy key is refused with `401` and `proxy_key_missing`.

## Example request

```bash Identification
curl -X POST "https://api.fingerly.io/api/v1/ingest" \
  -H "Content-Type: application/json" \
  -H "x-api-key: fly_pk_production_…" \
  -H "Idempotency-Key: 7d5e1f2a-3c4b-4d6e-8f90-a1b2c3d4e5f6" \
  -H "Origin: https://shop.example.com" \
  -d '{
    "sdk": { "platform": "web", "version": "0.1.0" },
    "consent": "granted",
    "signals": { "schema": 1, "…": "…" },
    "tag": "checkout:8412"
  }'
```

```bash Deferred report
curl -X POST "https://api.fingerly.io/api/v1/ingest" \
  -H "Content-Type: application/json" \
  -H "x-api-key: fly_pk_production_…" \
  -H "Origin: https://shop.example.com" \
  -d '{
    "token": "v1.eyJyZXF1ZXN0X2lkIjoi….…",
    "sdk": { "platform": "web", "version": "0.1.0" },
    "consent": "granted",
    "signals": { "tiers": ["deferred"], "…": "…" }
  }'
```

## Example response

```json 200
{
  "request_id": "01a0a84b-e6a2-7c09-9f51-0b3d7a26c8e4",
  "deferred_token": "v1.eyJyZXF1ZXN0X2lkIjoi….…",
  "visitor_id": "X9pL2mRc7KvT4bQw8NdF",
  "visitor_is_new": false,
  "identifiable": true,
  "visitor_confidence": 100,
  "state": "enriched",
  "suspect_score": 37,
  "suspect_level": "high",
  "triggers": [
    {
      "signal": "tor",
      "group": "tor",
      "weight": 14,
      "confidence": "high"
    },
    {
      "signal": "automation",
      "group": "bot",
      "weight": 9,
      "confidence": "medium"
    },
    {
      "signal": "tampering",
      "group": "browser_tampering",
      "weight": 8,
      "confidence": "medium"
    },
    {
      "signal": "high_activity",
      "group": "high_activity",
      "weight": 6,
      "confidence": "low"
    }
  ]
}
```

```json 202
{
  "request_id": "01a0a84b-e6a2-7c09-9f51-0b3d7a26c8e4"
}
```

```json 422
{
  "error": {
    "code": "invalid_supplement",
    "message": "the deferred report or token is not valid",
    "status": 422
  },
  "request_id": "01a0a84c-0f11-7a3e-9c2d-4b5e6f708192"
}
```
