# Editor sessions

Let your users prepare a draft envelope or a template in the eSignStack editor, inside your app or on a hosted page, without an eSignStack account.

Your server creates an editor session and gets back a single-use URL. You load it in an iframe (`embedded`) or send the browser to it (`hosted`). The person can only do what the session allows.

## Create a session

```http
POST /api/v1/editor_sessions
Authorization: Bearer rk_live_…
Content-Type: application/json
Idempotency-Key: order-456-edit-1

{
  "target": "env_01J…",
  "mode": "embedded",
  "parent_origin": "https://app.example.com",
  "capabilities": { "edit_documents": true, "edit_recipients": true, "edit_fields": true, "send": false },
  "actor": { "name": "Jane Doe", "email": "jane@example.com", "external_id": "user_123" }
}
```

| Field           | Notes                                                                 |
| --------------- | --------------------------------------------------------------------- |
| `target`        | A draft envelope (`env_…`) or a template (`tpl_…`) in the key's mode. A test key opens test envelopes and templates. A sent envelope returns `409`; use [corrections](/docs/envelopes#corrections) instead. |
| `mode`          | `embedded` or `hosted`                                                |
| `parent_origin` | Required for `embedded`. Must be an origin in **Settings → Embedding**. |
| `return_url`    | Required for `hosted`. Must be an HTTPS URL on an allowed return origin. |
| `capabilities`  | At least one of `edit_documents`, `edit_recipients`, `edit_fields` and `send`. |
| `actor`         | Who your app says is editing. Recorded with every change in the history. |

Capabilities can't go beyond the key. Editing an envelope needs `envelopes:write`, editing a template needs `templates:write`, and `send` needs `envelopes:send`. Templates can't be sent. The server checks the capability and the key's ability on every change, so removing an ability from the key stops those changes in open sessions.

The response includes `id` (`ses_…`), `url` and `expires_at`. Open the URL within 10 minutes. After that the session lasts 60 minutes without activity and 8 hours at most. It also ends if the key that created it expires or is revoked.

## Embedded sessions

Put the URL in an iframe. The page can only be framed by `parent_origin`. The editor posts messages to that origin, with the name in a `type` key:

| `type`                       | When                                     |
| ---------------------------- | ---------------------------------------- |
| `esignstack:editor.ready`    | The editor loaded                        |
| `esignstack:editor.saved`    | The person saved and finished            |
| `esignstack:editor.sent`     | The person sent the envelope             |
| `esignstack:editor.cancelled`| The person left without saving           |
| `esignstack:resize`          | The content height changed (`height`)    |

Each message also has `session`.

## Hosted sessions

When the person finishes, the browser goes to:

```text
https://app.example.com/after-edit?session=ses_…&status=saved&target=env_…
```

`status` is `saved`, `sent` or `cancelled`.

## Confirm what happened

Messages and redirects only update your interface. Check the result with `GET /api/v1/envelopes/{id}` or the `envelope.sent` [webhook](/docs/webhooks) before acting on it.
