---
title: "List structured envelope fields"
method: GET
path: "/envelopes/{envelopeId}/fields"
tags: ["Envelopes"]
---

# List structured envelope fields

`GET /envelopes/{envelopeId}/fields`

## Request

- Base URL: `https://inkseal.net/api/v1`
- URL: `https://inkseal.net/api/v1/envelopes/{envelopeId}/fields`
- Auth: HTTP bearer

Returns every field in document order: page, vertical position, horizontal position, then public id. Unlike create requests and nested signer fields, `page` is a one-based page number. The endpoint is available in every envelope status.

Named and unnamed fields are both returned. Signature and initials image bytes stay private. A filled image field carries a credential-authenticated `signature.url`; send the same bearer credential when following it. The URL itself does not expire, so `expiresAt` is null, but every read rechecks credential and workspace access. An envelope in another workspace answers 404.

## Response `200`

The envelope's structured fields in deterministic document order.

- object
  - `data` StructuredEnvelopeField[], required
    - `id` string, required: Public field id. This is the `fieldId` in `/envelopes/{envelopeId}/fields/{fieldId}/signature`.
    - `name` string, nullable, required: Stable integration name, or null for an unnamed ad hoc field.
    - `type` 'signature' | 'initials' | 'text' | 'date' | 'checkbox' | 'number' | 'email' | 'select' | 'radio' | 'textarea', required: How the field is filled and rendered. Values are stored as strings; signature and initials use images.
    - `label` string, nullable, required
    - `assignee` union, required
      - 'sender'
      - object
        - `signerId` string, required: Public signer id.
    - `required` boolean, required
    - `readonly` boolean, required
    - `page` integer, required: One-based document page number.
    - `bounds` object, required
      - `xRatio` number, required
      - `yRatio` number, required
      - `widthRatio` number, required
      - `heightRatio` number, required
    - `value` string, nullable, required: Stored wire value, or null when unfilled.
    - `valueLabel` string, nullable, required: The selected option label for select and radio fields. Null for other types and unfilled choices.
    - `validation` object, nullable, required
      - `minLength` integer
      - `maxLength` integer
      - `pattern` string
      - `min` number
      - `max` number
      - `minDate` string, date
      - `maxDate` string, date
    - `options` object[], nullable, required
      - `value` string, required
      - `label` string, required
    - `filledAt` string, date-time, nullable, required
    - `filledBy` 'sender' | 'signer' | 'null', nullable, required
    - `signature` object, nullable, required
      - `url` string, required: Credential-authenticated API path for the image.
      - `expiresAt` unknown, required

## Other responses

- `401`: The credential is missing, malformed, unknown, expired, revoked, or past its rotation grace window. Code: `unauthorized`. Every authentication failure is deliberately indistinguishable.
- `403`: The credential is valid but may not do this. Codes: `insufficient_scope` (the route's scopes are not all held; `details` names `requiredScopes` and `missingScopes`), `forbidden` (the capability check on the resolved resource failed), `scope_escalation` (a grant wider than the caller's own was requested).
- `404`: The resource does not exist, was deleted, or belongs to another workspace. Code: `not_found`. The three cases are answered identically on purpose, so a 404 never confirms that an identifier exists elsewhere.
- `429`: A limit was reached. Codes: `rate_limited` (the credential's per-bucket HTTP limit, or the per-workspace detection throttle), `workspace_limit_exceeded` (a workspace content or send limit; `details.limit` names it), `daily_budget_exceeded` (the workspace's daily detection budget). The four rate-limit headers are sent on this response and on no successful one, so a client cannot read its remaining budget without being refused. Retrying after `Retry-After` is always safe: a rate-limit refusal happens before the handler runs.
- `503`: A dependency the request needs is unreachable and nothing was changed. Codes: `queue_unavailable` (a background job could not be enqueued; retry the call), `billing_unavailable` (Stripe would not open a checkout session; nothing was charged, retry the call), `service_unavailable` (the rate-limit store is down, so the request was refused before running).

---

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