---
title: "Start a hosted attestation session"
method: POST
path: "/api/v1/upload-sessions"
tags: ["Hosted Attestation"]
---

# Start a hosted attestation session

`POST /api/v1/upload-sessions`

## Request

- Base URL: `https://easy2257.com`
- URL: `https://easy2257.com/api/v1/upload-sessions`
- Auth: HTTP bearer

Hands the whole attestation step to Easy2257. You post the content facts, redirect the uploader to `hostedUrl`, and Easy2257 renders the form, captures the producer attestation with IP, user agent and timestamp, and tells you when it is done. Your platform builds no compliance UI. `detectedFaceCount` chooses the path: 1 records a solo attestation and fires `upload_session.solo_completed`; 2 or more opens a collab scene from the collaborators the uploader names, emails them, and fires `collab_scene.created` carrying `uploadSessionId` so you can correlate it back to the content row. The uploader must already have an active solo account under your partner account. Sessions last 24 hours, and each call creates a new one.

## Request body

- CreateUploadSessionBody
  - `contentId` string, required: Your content id. Echoed back to you on the completion webhook so you can find the row again.
  - `contentType` 'image' | 'video' | 'gallery', required
  - `contentTitle` string, required
  - `detectedFaceCount` integer, required: How many people your pipeline detected in the upload. This alone chooses the path: 1 collects a solo attestation, 2 or more opens a collab scene and emails every collaborator the uploader names.
  - `uploaderExternalUserId` string, required: Your user id for the uploader. Must already map to an active Easy2257 solo account under your partner account.
  - `uploaderEmail` string, email, required
  - `uploaderFirstName` string
  - `uploaderLastName` string
  - `callbackUrl` string, uri, required: Required, stored for your reference. Events go to your portal-registered endpoints.
  - `redirectUrl` string, uri, required: Required. Where the hosted form returns the uploader when they are done.

## Response `201`

Session created. Redirect the uploader to `hostedUrl`.

- UploadSessionResponse
  - `sessionId` string, required
  - `token` string, required: 64-character session token. Treat it as a secret: anyone holding it can complete the attestation.
  - `hostedUrl` string, uri, required: Send the uploader here in top-level navigation. Easy2257 hosts the attestation form, so you build no compliance UI at all.
  - `status` 'created', required
  - `expiresAt` string, date-time, required: 24 hours from creation. After that the uploader needs a new session.

## Other responses

- `400`: Validation failure. `code` is `missing_field` or `invalid_field`, and `field` names the offender.
- `401`: No `Authorization: Bearer` header, or a key that is unknown, revoked, or expired. The body carries only `error`, never a `code`.
- `403`: Rejected before the handler: a test-mode key (`TEST_MODE_UNAVAILABLE`) or a partner account that is not ACTIVE. Never used for cross-partner access, which returns 404.
- `409`: The uploader has no active Easy2257 solo account under your partner account. `code` is `uploader_not_solo_active`. Run them through solo onboarding first.
- `429`: Rate limit exceeded: 300 requests per 60 seconds per API key, shared across all `/api/v1` endpoints (requests without a `Bearer` key fall back to 60 per 60 seconds per client IP, and a per-address flood ceiling of 1200 per 60 seconds also applies). Honor `Retry-After`.
- `500`: Server error. Retry with exponential backoff.

---

[API](https://skmtc.dev/easy2257/apis/easy2257-partner-api.md) · [All operations](https://skmtc.dev/easy2257/apis/easy2257-partner-api/llms.txt) · [OpenAPI document](https://skmtc.dev/easy2257/apis/easy2257-partner-api/revisions/f880026c1f04?raw)
