> For the complete documentation index, see [llms.txt](https://docs.facephi.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.facephi.com/docs.facephi-en/rest-api/midapi-v2/document-services/document-validation/subida-de-assets.md).

# Asset Upload

Document Validation does not receive files directly: it consumes the assets already uploaded to the Facephi storage service, referenced by their `fileKey`. Before starting a validation, upload each asset (document and, optionally, selfie) with the storage endpoint.

### Before uploading: create the operation

Assets belong to an **operation**, which is their container and lifecycle. The operation identifier **is not a free business datum**: it is the one issued by `POST /operation`, and it is the first segment of every asset key.

```
POST /operation
```

```json
{
  "operationId": "0192a3f4-7b21-7c44-9e1a-3f5b8c2d1e04",
  "timestamp": "2026-06-26T12:00:00Z",
  "expiresAt": "2026-06-26T12:15:00Z"
}
```

The operation **expires** at the time indicated by `expiresAt`. Once it expires, assets can no longer be uploaded under it or referenced: you must create a new operation and upload the assets again. See [Operations](/docs.facephi-en/rest-api/midapi-v2/operations.md).

{% hint style="warning" %}
If your integration had been using its own operation identifier (of the type `consumerX/op-123`) it must switch to using the one returned by `POST /operation`. An identifier with another format is rejected with `400`.
{% endhint %}

### Endpoint

```
POST /storage
```

### Headers

| Name              | Type   | Required | Description                                                                                                             |
| ----------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------- |
| **Authorization** | string | **Yes**  | consumer Token in format `Bearer <token>` (see [Authentication](/docs.facephi-en/rest-api/midapi-v2/autenticacion.md)). |
| **consumer-id**   | string | **Yes**  | Consumer identifier.                                                                                                    |

This endpoint does not carry a header `operation-id`: the operation goes in the body, in `operationId`.

### Request body

**Content-Type:** `application/json`

#### Parameters

| Parameter       | Type   | Required | Description                                                                                                                                                                                      |
| --------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `operationId`   | string | **Yes**  | Identifier of the operation to which the asset belongs, as returned by `POST /operation`.                                                                                                        |
| `asset`         | object | **Yes**  | Asset to save.                                                                                                                                                                                   |
| `asset.context` | string | **Yes**  | Asset type (see the types table below).                                                                                                                                                          |
| `asset.file`    | string | **Yes**  | Asset content (document token or selfie), encoded in **Base64**. For `TOKEN_FRONT_DOCUMENT` and `TOKEN_BACK_DOCUMENT` it must be the **RAW token** of the document generated by the capture SDK. |

#### Request example

```json
{
  "operationId": "0192a3f4-7b21-7c44-9e1a-3f5b8c2d1e04",
  "asset": {
    "context": "TOKEN_FRONT_DOCUMENT",
    "file": "<base64>"
  }
}
```

### Responses

#### `200` Success

#### Response parameters

| Parameter   | Type   | Description                                                                                                                   |
| ----------- | ------ | ----------------------------------------------------------------------------------------------------------------------------- |
| `fileKey`   | string | Asset key, in the form `{operationId}/{CONTEXTO}`. It is the value that is resent **unchanged** when starting the validation. |
| `timestamp` | string | Response timestamp in format **ISO 8601**.                                                                                    |

#### Response example

```json
{
  "fileKey": "0192a3f4-7b21-7c44-9e1a-3f5b8c2d1e04/TOKEN_FRONT_DOCUMENT",
  "timestamp": "2026-06-26T12:00:03.000Z"
}
```

{% hint style="warning" %}
Resend the `fileKey` **as is**. Do not add the context to it (the key already includes it, and concatenating it again leaves a key that cannot be resolved), do not prepend any prefix, and do not split it. If you need to retrieve the keys of an operation, request them with `GET /operation/{operationId}/file-keys`, which returns them indexed by context.
{% endhint %}

#### Other responses

| Code  | Meaning                                                                                                                                                      |
| ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `400` | `operationId` does not have the expected format, the content does not correspond to the declared context, or the asset is empty or exceeds the maximum size. |
| `403` | The consumer is not provisioned with the service `STORAGE`.                                                                                                  |
| `404` | The operation does not exist or belongs to another consumer.                                                                                                 |
| `409` | There is already an asset of that context in the operation: there can be no more than one per context and operation.                                         |
| `410` | The operation has expired.                                                                                                                                   |

### Relevant asset contexts for the service

| Context                | Content                                                                                                               | Requirement  |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------ |
| `TOKEN_FRONT_DOCUMENT` | **RAW token** of the front side of the identity document (e.g. `tokenRawFrontDocument` generated by the capture SDK). | **Required** |
| `TOKEN_BACK_DOCUMENT`  | **RAW token** of the back side of the identity document (e.g. `tokenRawBackDocument` generated by the capture SDK).   | Optional     |
| `TOKEN_FACE_IMAGE`     | Holder selfie.                                                                                                        | Optional     |

{% hint style="warning" %}
**Important:** the document assets must be the tokens **RAW** of the front/back, not the processed tokens. If a non-RAW token is uploaded, validation cannot be executed and the transaction ends in `FAILED`.
{% endhint %}

{% hint style="info" %}
If no `TOKEN_FACE_IMAGE`, the service validates only the document: the signals derived from the selfie (facial comparison) are lost and the diagnosis is based only on document validations.
{% endhint %}

### Supported documents

* Document Validation validates **identity documents (ID)** and **passports**.
* For passports, the back side is not required: the front side is enough (`TOKEN_FRONT_DOCUMENT`).
* The specific set of **supported document types and countries/issuers** is defined in the **service registration**; check with Facephi for your integration.
* If the document is not supported or its Version cannot be validated, the transaction is resolved as `DECLINED` with the corresponding reason code (see [Result response](/docs.facephi-en/rest-api/midapi-v2/document-services/document-validation/respuesta-de-resultado.md)).

### Requirements and image quality

Capture quality determines whether the document can be validated. To maximize the approval rate:

* **Resolution** recommended minimum: HD (≥ 720×1080 px).
* **Size** maximum per file: 10 MB. Avoid aggressive compression; use the default values of a guided capture Flow.
* **Framing**: the document must appear **complete and uncropped**, occupying most of the frame and with a standard card aspect ratio.
* **Sharpness and lighting**: without blur, without reflections or glare that obscure data, and without excessive rotation.
* There can be no more than one asset of the same context for the same operation (a second upload of the same context returns `409 Conflict`). If you need to repeat an already uploaded capture, create a new operation.

{% hint style="info" %}
If a capture does not meet these requirements, validation flags it as a **quality/capture issue** (not fraud): these are the codes of the categories `input` and `integrity` (e.g. 100/101/104/105 and 102/103/106-111/500/501, see [Result response](/docs.facephi-en/rest-api/midapi-v2/document-services/document-validation/respuesta-de-resultado.md#rechazo-por-calidad-vs-deteccion-de-fraude)). In these cases, repeating the capture with better quality usually resolves the issue.
{% endhint %}
