> ## Documentation Index
> Fetch the complete documentation index at: https://developer.dromo.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Saving & Restoring Session Progress

Dromo's session auto-save feature lets users pick up an import exactly where they left off — even after navigating away, closing the browser, or returning days later. Sessions are stored server-side and can be restored across any device.

## How it works

When `savePartialSession` is enabled, Dromo continuously saves the user's progress in the background — capturing the active stage, column mappings, transformations, and the uploaded file. Progress is debounced and flushed automatically; no extra code is required.

To enable auto-save:

```javascript theme={null}
const importer = new DromoUploader("YOUR_LICENSE_KEY", fields, {
  backendSyncMode: "FULL_DATA",
  savePartialSession: true,
  importIdentifier: "contacts-import-v1",
});
```

<Note>
  `savePartialSession` requires `backendSyncMode: "FULL_DATA"` and a consistent
  `importIdentifier` to group sessions for the same import type.
</Note>

***

## Security model — the hydrationId

Sessions use a two-token model to prevent a leaked credential from granting permanent access:

| Token         | Lifespan                                        | Purpose                                                                               |
| ------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------- |
| `sessionId`   | Long-lived (7-day session TTL)                  | Backend session identifier — persist this durably; used to resume or delete a session |
| `hydrationId` | Short-lived (configurable TTL, default 6 hours) | Access token — passed to the widget to start or resume a session                      |

When a session is created, both tokens are returned. Pass the `hydrationId` to the widget. Store the `sessionId` server-side so you can mint a fresh `hydrationId` whenever the user returns.

<Warning>
  All session endpoints require your **backend** license key (`is_for_backend_api=True`). Never call these from client-side code.
</Warning>

***

## Starting a session

Call `POST /api/widget/session/v2/auth/` from your backend. The response includes a `sessionId` to store and a `hydrationId` to pass to the widget.

```bash theme={null}
curl --request POST \
  --url https://app.dromo.io/api/widget/session/v2/auth/ \
  --header 'X-DROMO-LICENSE-KEY: YOUR_BACKEND_LICENSE_KEY'
```

Optionally provide an `import_identifier` and a custom token TTL:

```bash theme={null}
curl --request POST \
  --url https://app.dromo.io/api/widget/session/v2/auth/ \
  --header 'X-DROMO-LICENSE-KEY: YOUR_BACKEND_LICENSE_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "import_identifier": "user_import_v1",
    "expires_in": 3600
  }'
```

| Field               | Required | Description                                                                                               |
| ------------------- | -------- | --------------------------------------------------------------------------------------------------------- |
| `import_identifier` | No       | A label for your own bookkeeping (e.g. schema name, import type). Not used for lookups. Defaults to `""`. |
| `expires_in`        | No       | Hydration token TTL in seconds. Defaults to `21600` (6 hours).                                            |

**Response:**

```json theme={null}
{
  "sessionId":   "1b6acf28-8748-4120-8d7a-4b7846d5e487",
  "hydrationId": "<signed-token>",
  "expiresIn":   21600,
  "savedAt":     "2026-06-19T18:00:00.000Z"
}
```

Store both values:

* **`sessionId`** — persist this server-side. It is needed to resume or delete the session later.
* **`hydrationId`** — pass this to the widget to begin the session.

***

## Restoring a session

When the user returns to resume an import, mint a fresh `hydrationId` from your backend using the stored `sessionId`, then pass it to the widget.

### Step 1 — Re-issue a hydrationId

```bash theme={null}
curl --request POST \
  --url https://app.dromo.io/api/widget/session/v2/SESSION_ID/auth/ \
  --header 'X-DROMO-LICENSE-KEY: YOUR_BACKEND_LICENSE_KEY'
```

Optionally set a custom TTL:

```bash theme={null}
curl --request POST \
  --url https://app.dromo.io/api/widget/session/v2/SESSION_ID/auth/ \
  --header 'X-DROMO-LICENSE-KEY: YOUR_BACKEND_LICENSE_KEY' \
  --header 'Content-Type: application/json' \
  --data '{ "expires_in": 3600 }'
```

| Field              | Required | Description                                                                                                 |
| ------------------ | -------- | ----------------------------------------------------------------------------------------------------------- |
| `SESSION_ID` (URL) | Yes      | UUID of the session to resume. Returns 404 if the session doesn't exist or hasn't been saved within 7 days. |
| `expires_in`       | No       | New token TTL in seconds. Defaults to `21600` (6 hours).                                                    |

**Response:**

```json theme={null}
{
  "hydrationId": "<signed-token>",
  "expiresIn":   21600
}
```

### Step 2 — Pass to the widget

```javascript theme={null}
const importer = new DromoUploader("YOUR_LICENSE_KEY", fields, {
  backendSyncMode: "FULL_DATA",
  savePartialSession: true,
  importIdentifier: "contacts-import-v1",
  hydrationId: freshHydrationId,
});
```

The widget uses the `hydrationId` to fetch the saved state and resume from where the user left off.

***

## Deleting a session

Sessions are automatically cleared when an import completes. To delete manually, send a `DELETE` request with the session's UUID and your **backend** license key:

```bash theme={null}
curl --request DELETE \
  --url https://app.dromo.io/api/widget/session/v2/SESSION_ID/ \
  --header 'X-DROMO-LICENSE-KEY: YOUR_BACKEND_LICENSE_KEY'
```

| Field              | Required | Description                    |
| ------------------ | -------- | ------------------------------ |
| `SESSION_ID` (URL) | Yes      | UUID of the session to delete. |

**Response:**

```json theme={null}
{ "success": true }
```

All hydration tokens for the session are immediately invalidated — any subsequent widget calls with the old `hydrationId` return 403. This call is idempotent and returns `success: true` even if the session was already deleted.

***

## Error reference

| Error                     | Meaning                                                      | Action                                                                   |
| ------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------ |
| `404` on resume or delete | Session not found or not saved within 7 days                 | Start a new session                                                      |
| `403` on widget call      | `hydrationId` invalidated (session deleted or token expired) | Re-issue a `hydrationId` via the resume endpoint, or start a new session |

***

## Full endpoint reference

All endpoints require `X-DROMO-LICENSE-KEY` (backend license key).

| Method   | Endpoint                                   | Description                                                                       |
| -------- | ------------------------------------------ | --------------------------------------------------------------------------------- |
| `POST`   | `/api/widget/session/v2/auth/`             | Create a new session. Returns `sessionId`, `hydrationId`, `expiresIn`, `savedAt`. |
| `POST`   | `/api/widget/session/v2/{sessionId}/auth/` | Re-issue a `hydrationId` for an existing session.                                 |
| `DELETE` | `/api/widget/session/v2/{sessionId}/`      | Delete a session and invalidate all its tokens. Idempotent.                       |
