---
title: "Create an organization seal"
method: POST
path: "/seals"
tags: ["Organization Seals"]
---

# Create an organization seal

`POST /seals`

Create a new organization seal with an uploaded, typed, or drawn image. Company-scope seals require a protected API key.

## Request body

- OrganizationSealCreate — Request body to create an organization seal.
  - `name` string, required — Internal name for the seal
  - `display_name` string, required — Display name rendered on the seal image
  - `signatory_title` string, nullable — Signatory title rendered on the seal image
  - `kind` 'uploaded' | 'typed' | 'drawn', required — How the seal image was created
  - `scope` 'company' | 'workspace', required — Scope of the seal. Company-scope requires a protected API key.
  - `workspace_id` string, uuid — Required when scope is 'workspace'
  - `image` string — Base64-encoded PNG data URI (data:image/png;base64,...). Required for 'uploaded' and 'drawn' kinds.
  - `typed` object — Typed seal parameters. Required for 'typed' kind.
    - `text` string — Text to render on the seal
    - `style` string — Style variant for the typed seal
  - `statement` SealStatement, required — Attestation statement affirming authority to apply the seal.
    - `language` string, required — Language code of the statement
    - `signatory_name` string, required — Name of the person attesting
    - `signatory_title` string, nullable — Title of the person attesting
    - `text` string, required — On create, the statement rendered with the authority name (the stored workspace or company name exactly as returned by the API, including HTML escaping). On replace, it must equal the seal's stored statement text.
    - `accepted` boolean, required — Must be true to confirm acceptance
    - `version` integer — Statement version number
  - `is_default` boolean — Set as default seal for this scope

## Response `201`

Seal created successfully

- OrganizationSeal — Organization seal metadata (image and statement internals are stripped from list/get responses).
  - `id` string, uuid
  - `lineage_id` string, uuid — Shared across versions of the same seal
  - `version` integer
  - `companies_id` string, uuid
  - `companies_workspaces_id` string, uuid, nullable — Null for company-scope seals
  - `authority_name` string, nullable — The name the seal was attested for: the company for company scope or the protected workspace, otherwise the workspace. Null for seals whose lineage was created before pinning; they certify in the company's current name.
  - `name` string
  - `display_name` string
  - `signatory_title` string, nullable
  - `kind` 'uploaded' | 'typed' | 'drawn'
  - `is_default` 0 | 1 — 1 if this is the default seal for its scope
  - `statement_language` string
  - `statement_version` integer
  - `signatory_name` string
  - `signatory_title_attested` string, nullable
  - `attested_at` string, date-time
  - `revoked_on` string, date-time, nullable
  - `created_at` string, date-time
  - `deleted` 0 | 1

## Other responses

- `400` — Bad Request - Validation failed
- `401` — Unauthorized - Invalid or missing API key
- `403` — Forbidden - Insufficient permissions
- `409` — Conflict. Possible codes: SEAL_ALREADY_REVOKED, SEAL_ORDER_COLLISION, SEAL_ERASE_NOT_ELIGIBLE
- `429` — Too Many Requests - Rate limit exceeded
- `503` — Seal image processing is unavailable on this host (SEAL_CREATION_DISABLED_EDGE). Retry against the primary API host.

## Changes

- **2026-09-17** `369590c8c416` — 1 info
  - added the optional property `authority_name` to the response with the `201` status
- **2026-09-15** `f179958c3bee` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/firma/apis/firma-partner-api/changes/seals/post.md)

---

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