← Plugin catalog
Developer Tools

SignatureAPI

Superposition Labs, Inc. v1.3.0

E-signatures for developers

Full description ↓

View on ChatGPT ↗

Save this plugin to Following and return to review observed changes. Follow up to 10 plugins free.

Description

From the marketplace listing

SignatureAPI is an e-signature API for developers: send documents for signature, embed signing in your app, and track progress with webhooks. Four skills design the signing flow, build and test the integration, diagnose one that misbehaves, and answer questions from the current docs. Test mode sends no real email. The hosted MCP server, signed in with OAuth, lets the agent create and inspect envelopes directly.

Language: English · Automatically detected from descriptions.

Competitor profile

From the developer’s listing and package; capabilities are not independently tested. Package observed Nov 3, 2026.

Declared capabilities

  • Interactive
  • Read
  • Write

Declared limitations

  • An unrelated document summary does not need a signing workflow.
  • A calendar request is outside the supported workflow.
  • An image request is outside the supported workflow.

Review scenarios; not an exhaustive list.

Cost & access

Pricing and account requirements have not been established from the available package declarations. Unknown pricing does not mean free access.

Starter prompt

Add e-signatures to this app with SignatureAPI.

View package source →

Keywords

Matches for “e-signature”

Exact text from the indicated source. A mention alone does not establish support for your task.

Publisher subtitle

E-signatures for developers

Publisher keywords · listing

e-signature esignature electronic-signature digital-signature document-signing signature-api webhooks mcp signatureapi

Publisher description

SignatureAPI is an e-signature API for developers: send documents for signature, embed signing in your app, and track progress with webhooks. This plugin adds skills to design, build and troubleshoot your integration and answer questions from the docs, plus the hosted MCP server.

Publisher full description

SignatureAPI is an e-signature API for developers: send documents for signature, embed signing in your app, and track progress with webhooks. Four skills design the signing flow, build and test the integration, diagnose one that misbehaves, and answer questions from the current docs. Test mode sends no real email. The hosted MCP server, signed in with OAuth, lets the agent create and inspect envelopes directly.

Files & skills

File archives

Plugin package35 files · 77.8 KBBrowse files →
Skill instructions
signatureapi-architecture20.9 KB

View saved version →

---
name: signatureapi-architecture
description: "Use when someone wants to add e-signatures or SignatureAPI to an app and the signing flow is not decided yet. Decides who signs, how they prove it is them, and what happens after. Also for a signing product or \"a platform like DocuSign\", even when the user knows no SignatureAPI terms. Writes a design brief or document, no code. Needs no API key."
---

# Design a SignatureAPI integration

## Purpose

Understand what the user wants their people to experience. Then decide how
SignatureAPI delivers it. Write a design brief or a design document, sized
to the product, and get an explicit yes. This skill writes no application
code. The `signatureapi-integrate` skill builds from what the user approved.

## When to reach for something else

- **Building against an approved design** belongs to `signatureapi-integrate`.
  It builds from the approved brief or document.
- **Diagnosing an integration that already exists** belongs to
  `signatureapi-diagnose`.
- **Whether SignatureAPI supports something** is answered by
  `signatureapi-docs`. Use it before you tell the user a capability exists
  or does not.
- **A different e-signature vendor** (DocuSign, Dropbox Sign, Adobe Sign, etc.)
  needs that vendor's own docs. Map the user's needs onto SignatureAPI's
  objects, not onto that vendor's.

## Keep the user's vocabulary

Keep the user's words for their product: a "contract", a "client", an
"onboarding step". Their code keeps its names too. Use SignatureAPI terms
only at the API boundary, and record the mapping in the design.

Ask every question in plain words; `references/plain-language-questions.md`
has the plain form of each decision. Tell the user two facts early: test
mode sends no real email, and a signer who is not logged in to the app is
reached by email.

## Understand the experience first

Before reading code and before naming any API object, establish four things
with the user:

- **The journey.** Who starts it, what they see, what the signer sees, and
  what happens after everyone has signed. Ask for the story in their words.
- **The actors.** Who sends, who signs, who approves, who only watches. Which
  of them are the app's own users and which are outsiders.
- **The success condition.** What must be true for the user to call this
  done. A signed PDF in a folder, a status on a record, an email, a
  dashboard entry.
- **The constraints.** Deadline, legal context, existing vendor, volume,
  budget, must-not-change parts of the app.

When the request already says most of this, restate it in one short
paragraph and ask only for what is missing. Ask in the user's words. Do not
ask about authentication methods, place types or routing yet.

Then ask one more question: **quick or thorough?** Offer the choice in one
line. "I can propose one recommended design and you confirm or correct it.
Or we explore alternatives together first." The answer sets the pace of the
rest of the conversation. Quick means: one recommended design, decisions
stated with their evidence, a short confirmation round. Thorough means:
present the alternatives, resolve the decisions in a few grouped rounds.

## Explore the codebase

Now read the code. Each signal below informs one decision and implies one
default. Record what you find; you will cite it as evidence.

- **Document origin.** Grep for PDF generation libraries, upload handlers,
  object storage clients, DOCX or templating code. Informs the document input
  path. Default: the app stores the file in its own storage and passes a
  signed or public URL. `POST /uploads` only when the app has no storage.
- **User authentication and a web frontend.** Grep for session or login
  code, and for a browser UI. Informs recipient authentication and whether
  the ceremony is emailed or embedded. Default: emailed link (`email_link`)
  for people outside the app. Embedded (`custom` plus `embeddable_in`) only
  for signers who are logged in to the app. Either can carry an extra
  challenge as a later array entry without changing who delivers the URL.
- **A native mobile app.** Look for an Xcode project, an Android Gradle
  module, or a React Native app. Informs whether signers sign inside the
  app. Default: a top-level WebView with `custom` authentication, created
  by the app's server (Shape 4 in `references/product-shapes.md`).
- **Tenancy.** Grep for organization, account, or tenant tables. Informs
  `sender` and `topics`. Default: one sender (the account's default) and no
  topics.
- **Webhook routes, queues, domain events.** Grep for existing inbound
  webhook handlers, job queues, event dispatch. Informs how events are
  handled and where envelope creation runs. Default: reuse the existing
  webhook route pattern and the existing background-job path.
- **Where third-party ids are persisted.** Grep for columns or tables that
  hold Stripe, Twilio, or similar ids. Informs where the envelope id goes.
  Default: a column on the domain row that motivated the signature.
- **PDF viewer or canvas components.** Grep for PDF rendering in the
  frontend. Informs whether a place-drawing UI is feasible. Default: no
  drawing UI. Use placeholders or `fixed_positions` set in code.
- **Design records.** Look for an ADR directory (`docs/adr`, `adr/`), a
  design-docs folder, or a decisions log. When one exists, the design
  document goes there, in that convention, with a pointer at the default
  path. An ADR directory counts even though this document is longer than
  one ADR.

The four placement questions in
`../signatureapi-integrate/references/brownfield-placement.md` cover the
call site, the inbound-HTTP path, and the persistence home. Answer them here.
Do not repeat them in the design document; link to the answers.

## Present the possibilities

Match the journey to the closest starting points in
`references/product-shapes.md`. Four common shapes are described there:
send-for-signature inside an existing app, an embedded signing step, a
self-serve platform, and signing inside a native mobile app. They are starting points, not a menu. Many products
combine two, or fit none. Say which shape is closest, what differs, and
what that difference costs. In thorough mode, present two or three
alternatives with their trade-offs. In quick mode, present one and say why.

## Decide progressively

- **Strong signal** in the code or the request: decide, and state the
  evidence.
- **Weak signal:** propose the default and ask for a yes.
- **No signal:** ask.

Always ask, even when you could infer it, when a decision changes what
people experience, the security of the signing, its legal standing, its
cost, or who owns the data. Decide everything else yourself and state it.

Ask in rounds, grouped by dependency: the document and its fields; the
signers and how they authenticate; what happens on completion; tenancy and
rollout. At most four questions per message, one decision each, with your
proposed answer beside it. Stop when the remaining decisions have a strong
signal or a confirmed default.

### Worked example: the first round

> You described this: a customer accepts a quote in your app, then your
> account manager and the customer both sign the order form, and the signed
> PDF goes onto the order. I found a PDF generator and an S3 client, so I
> propose your app generates the order form and uploads it. Two questions
> on the document before we get to the signers:
>
> 1. Does your app generate the order form, or do account managers upload
>    their own files? I propose generated.
> 2. Where should the signature boxes go: marked inside the generated
>    order form where they belong (my proposal), or at fixed spots you set
>    once?

## Decision matrix

The API-facing decisions, one row each. This table is for you; the user
sees the plain form in `references/plain-language-questions.md`. Every
identifier below is in the published spec. Check any you are unsure of before you write it into the
design:

    node ../signatureapi-integrate/scripts/openapi-explore.mjs schema Envelope.EnvelopeInput
    node ../signatureapi-integrate/scripts/openapi-explore.mjs schema Ceremony.CeremonyInput
    node ../signatureapi-integrate/scripts/openapi-explore.mjs schema Recipient.Type
    node ../signatureapi-integrate/scripts/openapi-explore.mjs schema Place.Type

| Decision | Options | Signals that pick one | Consequences | Default |
| --- | --- | --- | --- | --- |
| Document input path | A signed or public URL to a file in the app's own storage on a supported host (`../signatureapi-integrate/references/documents.md`); `POST /uploads` with the file bytes; a DOCX template merged with `data` | Object storage present → store there and pass a signed URL. No storage → `POST /uploads`. DOCX templates present → `format: docx` with `data`. A field-drawing UI → `POST /uploads`, because the structure read needs an upload id | The app keeps its own copy and record of the file. Upload URLs are temporary. DOCX `data` shapes the template fields the app must fill | A signed URL to the app's own storage |
| How places are defined | `[[place_key]]` placeholders in the file; `fixed_positions` in code; DOCX template fields plus places; a UI where users draw fields | App controls the document source → placeholders. Third-party PDF → `fixed_positions`. PDF viewer component present → drawing UI is feasible | A drawing UI needs page rendering, coordinate conversion, and reading the upload's structure (`inspect_upload`). It is the largest part of a platform | Placeholders when the app owns the file; `fixed_positions` otherwise |
| Recipient types and `routing` | The values in the current `Recipient.Type` schema; `routing` `sequential` or `parallel` | Approval step in the domain flow → `approver`. Fields filled before signing → `preparer`. Countersignature by the app owner → `automatic_signer`. A qualified-signature requirement → inspect `qualified_signer` and its account prerequisites | `sequential` notifies one recipient at a time. `parallel` notifies all at once | One `signer`; `sequential` |
| Authentication per recipient | An ordered array of `email_link`, `email_code`, `custom`, `identity_verification`. The first entry is the main method; later entries are extra challenges | Signer is logged in to the app → `custom`. Signer is outside the app → `email_link`. Regulated or high-value document → add a challenge to that main method, e.g. `[email_link, email_code]` for a signer outside the app, `[custom, email_code]` for one inside it | The **first** entry decides who delivers the ceremony URL: `email_link` first returns no URL and SignatureAPI emails the link and any code, so the app sends no email; `email_code` or `custom` first returns the URL for the app to deliver. `custom` is an assertion written to the audit log. `email_link` and `custom` are only valid first and cannot be combined; `email_code` appears at most once; `identity_verification` is never first and is enabled per account | `[email_link]` |
| Ceremony delivery and return | Emailed link; embedded with `embeddable_in`; embedded in a native app's WebView; `redirect_url` after the ceremony | Web frontend and logged-in signer → embedded. iOS or Android app and logged-in signer → native WebView, no `embeddable_in` for a top-level WebView. No frontend → emailed | Embedded ceremonies ignore `redirect_url`; the app learns the outcome from events. A native app catches them in its WebView navigation handler, and its server confirms the outcome. `redirect_url` receives the outcome, the envelope id and the recipient id as query parameters; the names are in the spec's `Ceremony.RedirectUrl` description | Emailed link, no redirect |
| On completion | Fetch deliverables and store them; notify the domain; do nothing beyond marking status | Object storage present → store the signed PDF there. Document model present → attach to it | `standard` deliverable includes the audit log; `simple` does not. `delivery_type: none` stops SignatureAPI emailing the deliverable to the recipient | Mark status on `envelope.completed`. On `deliverable.generated`, fetch `GET /envelopes/{envelopeId}/deliverables`, store the file at once (download URLs expire), mark the domain row |
| Rollout | Test mode only; test then live; who holds the live key | Env file with a `key_test_` key present → test first. Secrets manager present → live key goes there | Test envelopes send no email and are not binding. Live mode needs an active subscription on the account. A live key must never enter this skill's scripts | Test mode first. The user names who holds the live key and confirms live mode is active |
| Senders and multi-tenant | Account default sender; per-customer `sender` after `POST /senders` verification; `topics` per tenant | Tenant table present and customers send in their own name → per-customer sender. Tenant table present and one brand → default sender plus `topics` | A sender needs email verification before use. `topics` filter webhooks and envelope listings | Account default sender |
| Branding logo | No logo; a permanent PNG upload in the same account | A tenant or product logo exists → upload that PNG with `POST /uploads`, then make it permanent with `POST /uploads/{uploadId}/store` and a unique `key`. Or the user uploads it in the Dashboard Library | `branding.logo` accepts only the `url` of a permanent PNG upload in the same account. A website, CDN or signed storage URL is rejected. A temporary upload is rejected. Store the upload once and reuse its `url`; per-tenant logos need one stored upload each | No logo |
| Attestation | `none`, `mx_nom151`, `br_icp_brasil` | Mexican or Brazilian legal context in the domain → the matching value | Both paid options must be enabled at the account level | `none` |
| Envelope email content | Product wording in `title` and `message`; account anti-phishing content capability when the wording contains URL-, phone-, or numeric-date-like text | Required product copy contains any restricted pattern → record account enablement as a prerequisite | A stricter account policy can reject content that is valid under the JSON schema. Do not silently rewrite required copy | Plain text without restricted patterns for generic fixtures |

## Make scope explicit

For a design document, add a capability coverage table. Read the current
`Recipient.Type` and `Place.Type` schemas and give each value one line:
included now, or deferred with a reason. The first version's scope is not
the limit of SignatureAPI. Re-read the schemas when revising an old design.

## Cover the whole product, not only the API

For a design document, walk `references/coverage-checklist.md` once:
ownership, drafts and templates, tenant isolation, retention, repair paths,
volume, accessibility, non-goals. Take what this product needs. It is a
checklist for you, not a questionnaire; most items resolve from the journey
and the code.

## Brief or document

Match the output to the size of the product.

- **One signing flow** (a document, its signers, what happens after) → a
  design brief in chat. Write no file. Start with the journey in one
  sentence. Then give one plain line for each of these:
  - where the document comes from
  - who signs, in what order
  - how a signer proves it is them
  - where they sign
  - what happens when everyone has signed
  - trying it in test mode first

  Take the wording from `references/plain-language-questions.md`.
  Ask for an explicit yes. Then hand over to `signatureapi-integrate`.
- **A platform-shaped product** (users send their own documents, draw
  their own fields, or send in their own name; many tenants; "a platform
  like X") → the design document below.
- **The user asks for a document**, or the repository keeps design
  records for features like this → the design document below.

## Write the design document

Write it once the journey is confirmed, the shape is chosen, and every
decision that changes the data model, authentication or who receives email
has a yes.

Put it where the repository keeps design records (an ADR directory, a
design-docs folder), in that convention, with a one-line pointer at
`docs/signatureapi-integration.md`. Otherwise write it at that path.

Keep the template's headings. Delete a section only with a reason in Open
items. **For you** lines are the user's words, and the user approves them.
**Technical decision** lines are yours.

```markdown
# <the user's name for this feature> — SignatureAPI integration design

Date: YYYY-MM-DD
Status: draft | approved
Starting point: <closest shape from references/product-shapes.md, or "custom">
Departures from it: <one line each, or "none">

## The experience

- Journey:
- Actors:
- Success condition:
- Constraints:
- Non-goals:

## Vocabulary

| The user's term | Means, at the API boundary |
| --- | --- |
| <their term> | <envelope / recipient / place / ceremony / deliverable, and how> |

## Decisions

### Where the document comes from
- For you: <plain sentence, e.g. "Ledgerly makes the letter itself">
- Technical decision:
- Evidence or answer:
- Consequence:

### Where the signature and other fields go
- For you: <plain sentence>
- Technical decision:
- Evidence or answer:
- Consequence:

### Who takes part, and in what order
- For you: <plain sentence>
- Technical decision:
- Evidence or answer:
- Consequence:

### How a signer proves it is them
- For you: <plain sentence, one per kind of signer>
- Technical decision:
- Evidence or answer:
- Consequence:

### Where they sign, and where they land afterwards
- For you: <plain sentence>
- Technical decision:
- Evidence or answer:
- Consequence:

### What happens when everyone has signed
- For you: <plain sentence: where the signed file goes, who gets a copy by email>
- Technical decision:
- Evidence or answer:
- Consequence:

### Trying it safely, then going live
- For you: <plain sentence: test mode sends no real email; who holds the live key>
- Technical decision:
- Evidence or answer:
- Consequence:

### Whose name is on the email
- For you: <plain sentence>
- Technical decision:
- Evidence or answer:
- Consequence:

### Legal timestamp for Mexico or Brazil
- For you: <plain sentence, or "not needed">
- Technical decision:
- Evidence or answer:
- Consequence:

## Product coverage

<one short entry per applicable area from references/coverage-checklist.md:
ownership and permissions; drafts and templates; tenant isolation; sensitive
data and retention; idempotency, reconciliation and repair; volume and
observability; accessibility, mobile, localization, branding>

## SignatureAPI capability coverage

| Area | Provider capability | Included now? | If deferred, why |
| --- | --- | --- | --- |
| Recipient type | <one current `Recipient.Type` value> | yes / no | <reason or n/a> |
| Place type | <one current `Place.Type` value, or a group with one disposition> | yes / no | <reason or n/a> |

## Account prerequisites

- <account capability needed by an approved decision, including restricted
  `title` or `message` content; or "none">

## Endpoint sequence the application calls

1. <method and path, and where in the codebase it is called from>

## Events the application handles

- <event type> — <what the handler does>

## What the application persists

- <field or table> — <what it holds>

## Open items

- <anything still unanswered>
```

Present the document to the user. Ask for an explicit yes on The
experience section and the For you lines; read them out, not the technical
lines. Set `Status: approved` only after the user says yes. The file is the contract
`signatureapi-integrate` reads. Do not start building.

## Red flags

| Thought | Reality |
| --- | --- |
| "I'll read the code first, then ask." | The code says where signing fits, not what people should experience. Ask that first. |
| "This is obvious, I'll skip the design." | Document source, field placement and completion handling are where a wrong guess costs days. A brief takes one message. |
| "Every flow needs the full document." | One signing flow needs a brief. The document is for platform-shaped products, or on request. |
| "They said 'like X', so I'll copy X's data model." | X's templates, drafts and tabs are not SignatureAPI's objects. Map the user's needs onto this API. |
| "I'll pick sensible defaults and note them." | `custom` authentication, a placeholder scheme and where the PDF is stored are product decisions. Propose them and get a yes. |

## References

- `references/product-shapes.md` — four common starting points: what the app calls, what you prove it with
- `references/plain-language-questions.md` — each decision as a plain question, with the technical meaning of each answer
- `references/coverage-checklist.md` — the product-design areas beyond API configuration
- `../signatureapi-integrate/references/brownfield-placement.md` — where signing belongs in an existing codebase
- `../signatureapi-integrate/references/verification-loop.md` — why `custom` authentication is only for signers the app verified

## Vocabulary

An **envelope** holds **documents** and **recipients**. **Places** are
regions on a document bound to a recipient. Each recipient signs through a
**ceremony**. Completion produces a **deliverable**. The **design
document** is `docs/signatureapi-integration.md`.

Referenced files: 3 — file references are metadata, not package contents.

signatureapi-diagnose6.23 KB

View saved version →

---
name: signatureapi-diagnose
description: "Use when an existing SignatureAPI integration misbehaves. Covers an envelope stuck in processing, a missing webhook or signing email, an invalid or expired link, a missing signed document, or a 4xx error. Use it even for one missing email; test mode never sends real email. Read-only; safe on live envelopes."
allowed-tools: Read, Grep, WebFetch(domain:signatureapi.com), WebFetch(domain:spec.signatureapi.com)
inputs:
  - name: SIGNATUREAPI_KEY
    required: true
---

# Troubleshoot SignatureAPI

Start here: `node scripts/diagnose-envelope.mjs --envelope <id>`. It fetches
the envelope and its events in one pass and prints a verdict with next steps.

## When to reach for something else

- **Deciding how an app should use SignatureAPI** belongs to
  `signatureapi-architecture`.
- **Building a new signing flow** (creating envelopes, placing signature
  fields, wiring up a webhook for the first time) belongs to
  `signatureapi-integrate`.
- **How SignatureAPI is documented to behave** belongs to
  `signatureapi-docs`. Use it to compare an envelope's state with the
  documented behavior.
- **A webhook that is not a SignatureAPI webhook** belongs to whatever sent
  it. The symptoms and event shapes below are specific to SignatureAPI.
- **A different e-signature vendor** (DocuSign, Dropbox Sign, Adobe Sign,
  etc.) needs that vendor's own docs. The failure codes and symptoms here
  are SignatureAPI-specific.
- **A project with no SignatureAPI credentials present** has no envelope to
  diagnose yet. Confirm that first. Do not run this skill's scripts against
  a key that does not exist.

## Access

These are your tools for reading state. The customer's application does not
depend on them. The application integrates against the REST API
(`https://api.signatureapi.com/v1`, header `X-API-Key`). While diagnosing,
use MCP first (`https://mcp.signatureapi.com/mcp`): `whoami`, `get_envelope`
(takes `envelope_id`, not `id`), `list_envelopes`, `list_events`,
`list_webhooks`, `list_webhook_attempts`, `get_deliverables`, `list_emails`,
`get_email`. Reads by id work on test and live
envelopes alike. Listings take a per-call `mode` and default to test;
`whoami.modes.live` indicates access, not a session mode. Call `whoami`
only for an account question or a needed live-access check. Fall back to REST when a tool is missing. For documented behavior, use
`signatureapi-docs`. When you have to fall
back, report the gap at https://github.com/signatureapi/skills/issues/new.

Identifiers named below (paths, event types, status codes) are illustrations.
The published spec at `https://spec.signatureapi.com/openapi.yaml` is the
source of truth, and wins if the two disagree.

This skill only reads. Every script issues GET requests, so it is safe
against a live key during an incident. Each script reports the mode it ran
in. Run a script with `node --env-file=<project env file> scripts/…` so the
key loads without being printed.

The repair is a separate decision. Once the verdict is clear, name the fix
and ask before applying it. `resend_request` for a signer who lost the
email. `replace_recipient` for a bounced or wrong address. `create_ceremony`
for an expired link. In live mode each one emails a real person.

Read `SIGNATUREAPI_KEY` from the environment only. Never pass it as a
command-line argument. Argv is exposed in shell history and process listings
on any shared or logged system.

## Symptoms

### Envelope stuck in `processing`
Documents are still being fetched and prepared. Almost always an unreachable
document URL. Check two things: does every document URL return 200 to an
anonymous request, and is each file a valid PDF or DOCX?

### No webhook arrived
Split the question in two. Did the event happen? `list_events` with the
`envelope_id`, or `GET /envelopes/{envelopeId}/events`. Was it delivered?
`list_webhook_attempts` for the endpoint shows each delivery and the
response code your handler returned. No attempt means the endpoint is not
subscribed to that event type, or is in the other mode. A non-2xx attempt
means your handler ran and failed. A 401 or 400 on every attempt usually
means signature verification fails. Check three things: the handler
verifies the raw body, not re-serialized JSON; it reads the `webhook-id`,
`webhook-timestamp` and `webhook-signature` headers; and its secret belongs
to this endpoint and mode. Test and live endpoints are separate. A
test envelope never notifies a live endpoint.

### Recipient never got the email
In **test mode no email is ever sent**. That is by design. Read what would
have been sent with `list_emails`, then `get_email`. Only test signing-request emails expose rendered content and ceremony
links. Authentication-code subjects and content are withheld. In live mode, look for
`recipient.soft_bounced` / `recipient.hard_bounced` events.

### Ceremony link does not work
Links are single-recipient and expire. For `email_link` recipients the link
is the authentication. So the API never returns it in live mode. Only the
test-mode email log exposes it.

### Deliverable missing after completion
Check for a `deliverable.generated` event, then `get_deliverables` (or
`GET /envelopes/{envelopeId}/deliverables`). A `pending` or `processing`
status means not yet, not missing.

### "Invalid link" or an expired link
Creating a ceremony revokes every earlier link for that recipient. Look for
code that creates ceremonies more than once: a retried webhook handler, or
an email scanner opening a link that creates one on open. Links also expire,
after 30 days by default. The fix is a fresh link (`create_ceremony` or a
resend). Ask before applying it.

### Envelope creation rejects the document
- The URL host is not a supported storage host: upload the file instead.
- "Could not be parsed as a PDF" on a DOCX: `format` is missing.
- A DOCX from Google Docs, LibreOffice or a DOCX library fails to parse:
  re-save it in Microsoft Word.
- A placeholder is "not found" in a PDF printed from HTML: ligatures or
  zero-width characters split the marker text.

### 422 on create
See `references/errors.md` for the response shape and the most common cause.
Check the exact schema in the OpenAPI spec at
`https://spec.signatureapi.com/openapi.yaml`.

## References

- `references/errors.md` — HTTP status codes and what they mean here

Referenced files: 5 — file references are metadata, not package contents.

signatureapi-docs4.16 KB

View saved version →

---
name: signatureapi-docs
description: "Use when a question about SignatureAPI needs a documented answer: how a feature works, what the API accepts, webhook behavior, signing flows, limits, or why something happened. Use it even when you think you know the answer, and even when the user knows no SignatureAPI terms. Not for other vendors' docs."
allowed-tools: WebFetch(domain:signatureapi.com)
---

# Research the SignatureAPI docs

## Purpose

Answer SignatureAPI questions from the current published docs. Link a page
for every claim. Find pages by meaning, not by keyword. Read each page live
and in full. Keep no copy between questions.

## When to reach for something else

- **Field names, types and allowed values** come from the OpenAPI spec.
  Query it with the `openapi-explore.mjs` script bundled with
  `signatureapi-integrate`. Without a shell, read
  `https://spec.signatureapi.com/openapi.yaml`.
- **Deciding how an app should use SignatureAPI** belongs to
  `signatureapi-architecture`.
- **Writing code that calls SignatureAPI** belongs to
  `signatureapi-integrate`.
- **An envelope that misbehaves** belongs to `signatureapi-diagnose`. This
  skill explains documented behavior. It does not read account state.
- **Another vendor's product** needs that vendor's own docs.

## Keep the user's vocabulary

Answer in the user's words. Map each of their concepts to a SignatureAPI
term only to choose pages. Name a SignatureAPI term only for an API field,
an event, or a page title.

## Sources, in order

1. Docs pages found through the docs index,
   `https://signatureapi.com/llms.txt`. Fetch each page as page Markdown.
2. `search_documentation` on the SignatureAPI MCP server. Use it only for
   an exact string: an error message, an event name, a field name. Its
   index can lag the live pages. With `page` set to a page path from the
   docs index, it returns that page in full. Use this when you cannot fetch
   URLs.
3. A web search limited to `site:signatureapi.com`.

Memory is not a source. Do not state a fact you did not read in this
session, even when you are sure of it.

## Find the pages

1. List the concepts the question needs, in the user's words.
2. Fetch the docs index at `https://signatureapi.com/llms.txt`. Never guess
   a docs URL.
3. Pick one to three pages whose titles or descriptions cover those
   concepts. Choose by meaning. The user's words often differ from the
   page's words.
4. Fetch each page as page Markdown. Read the whole page, not an excerpt.
   Some fetch tools return a summary instead of the page. With a shell,
   save the raw text with `curl -s -o <file> <page URL>.md`. Put the file
   in a temporary directory, never in the user's project. Read the file in
   full, in parts if the host limits output. Do not search it for
   keywords. Otherwise ask the fetch tool for the full text verbatim. Read
   the docs index the same way.
5. Follow links in the page that bear on the question. Fetch them the same
   way.
6. Check each claim you plan to make against the text you read.

If a claim is still open, change the angle and repeat steps 3 to 6:

- Try a related concept, or the parent or child page.
- Look up an exact string with `search_documentation`. Use two to six
  title-like words, never the whole question.
- Search the web with `site:signatureapi.com`.

Stop after three rounds. Stop sooner once every claim has a page.

## Answer

- Link the page for every documented claim.
- Mark anything you worked out, rather than read, as your inference.
- When two pages disagree, say so and link both.
- When the docs do not cover the question, say so. Point to the OpenAPI
  spec or to SignatureAPI support. Do not fill the gap from memory.
- When you cannot fetch pages, say the answer is unverified. Name the page
  the user should check.
- Ask the user a question only when the answer changes which page applies.

## Vocabulary

- **Docs index**: `https://signatureapi.com/llms.txt`. It lists every
  published docs page with a one-line description.
- **Page Markdown**: a docs page as Markdown, at the page URL plus `.md`.
- **OpenAPI spec**: `https://spec.signatureapi.com/openapi.yaml`. It is the
  source of truth for field names, enum values, events, paths and limits.
signatureapi-integrate13.7 KB

View saved version →

---
name: signatureapi-integrate
description: "Use when writing or changing code that calls SignatureAPI once the signing flow is agreed. Covers creating envelopes, placing signature fields, handling SignatureAPI webhooks, embedding signing, and sending one test envelope. Use it even for a single envelope, and in hosts without a repository. Works in test mode."
inputs:
  - name: SIGNATUREAPI_KEY
    required: true
---

# Integrate SignatureAPI

## When to reach for something else

- **Deciding who signs, how, and what happens after** belongs to
  `signatureapi-architecture`.
- **An integration that already misbehaves** belongs to
  `signatureapi-diagnose`.
- **How a SignatureAPI feature behaves**, in prose, belongs to
  `signatureapi-docs`. Use it before you answer from memory.
- **Another vendor's webhooks or API** (DocuSign, Dropbox Sign, Adobe Sign)
  need that vendor's docs. Do not carry their concepts into SignatureAPI.
- **No SignatureAPI account yet.** Ask whether the user has chosen
  SignatureAPI. If not, stop.

## Two surfaces

**The application calls the REST API.** The code you deliver uses the
codebase's own language and HTTP client against
`https://api.signatureapi.com/v1`, with the `X-API-Key` header. There is no
SDK. The app never depends on MCP, the CLI or this skill's scripts.

**You work with MCP, the CLI and the scripts.** This skill works in test
mode only. Test keys start with `key_test_`.

- **MCP** (`https://mcp.signatureapi.com/mcp`) inspects and exercises the
  API. MCP mode is per call: pass `mode: "test"` explicitly when creating
  and listing. `whoami.modes.live` is permission to use live mode, not the
  current mode. Reads by id follow the resource's mode. Never pass `live`
  without the user's explicit intent. Check the mode a create returns; if an
  unintended live envelope was created, stop and tell the user. Its tools,
  by job:
  - Documents: `upload_file` or `mint_upload_url`, `inspect_upload`.
  - Envelopes: `create_envelope`, `get_envelope` (takes `envelope_id`),
    `list_envelopes`, `cancel_envelope`, `delete_envelope` (final status
    only; cancel first).
  - Recipients: `resend_request`, `replace_recipient`, `create_ceremony`.
  - Watching: `list_events`, `get_deliverables`, `list_emails`,
    `get_email`.
  - Session: `whoami`. Call it only when the user asks which account is
    connected or a requested live action needs an access check.
  - Webhooks: `list_webhooks`, `create_webhook`, `update_webhook`,
    `list_webhook_attempts`, `delete_webhook`.
  - Docs: `search_documentation`. Reach it through `signatureapi-docs`,
    which decides when a keyword search helps.
- **The CLI** (`npx --yes signatureapi <command>`) handles secrets and
  local ports when you have a shell. `init` writes the test key to the
  env file. `listen` tunnels test webhooks to a local handler and writes
  their signing secret. `trigger <event type>` sends one example event.
  `api-keys list --mode test` shows key metadata. `whoami` names the
  account the CLI acts for. No command prints a secret. Never run a CLI command with
  `--mode live`.
- **The scripts** here read the contract and drive a test envelope. See
  Scripts below.

A missing MCP tool does not prove a REST operation exists. Confirm it with
`node scripts/openapi-explore.mjs operation <method> <path>` first. If that
fails, stop and report the gap at
https://github.com/signatureapi/skills/issues/new.

Do not collect government IDs, health information, payment-card data,
biometric verification, passwords, or authentication codes through the
plugin. This applies to documents, metadata, template values and free text.
Use synthetic test data. Custom authentication evidence stays in the user's
application; plugin inputs accept only non-secret audit references and
timestamps. Never ask the user to paste credentials into chat.

## Know your host

- **A shell:** use the CLI and the scripts. **No shell:** use MCP for every
  step, and the dashboard for credentials.
- **Upload tool:** your client lists `upload_file` (takes a host-provided
  file reference), `mint_upload_url` (returns a URL to send the bytes to),
  or both. With both, use `mint_upload_url` for local files with a shell
  and `upload_file` only for host-provided file references. Never invent a
  file reference.
- **No filesystem:** do not ask for the key. MCP is already authenticated.
- **No repository** (a chat host such as ChatGPT): design with
  `signatureapi-architecture` and prove the flow with MCP in test mode.
  Hand over the design and the proven request bodies. Say that the code is
  written in a coding environment with the repository open.

## The spec decides facts

`https://spec.signatureapi.com/openapi.yaml` is the source of truth for
field names, enum values, events, paths and limits. Where this skill and
the spec disagree, the spec wins. Query it before writing a request body or
a handler; the docs pages are too large for this.

    node scripts/openapi-explore.mjs operations [filter]
    node scripts/openapi-explore.mjs operation post /envelopes
    node scripts/openapi-explore.mjs schema Place.PlaceInput
    node scripts/openapi-explore.mjs webhooks
    node scripts/openapi-explore.mjs check-request get '/envelopes/<id>/deliverables?limit=20'

`check-request` validates a request locally and sends nothing. For prose,
use `signatureapi-docs`.

## Setup

The key goes into the project's gitignored env file without passing through
the chat. No MCP tool returns a credential.

1. For MCP-only work, OAuth already authenticates calls; no API key is
   needed. For application code or the bundled REST scripts, set up the key:
2. **With a shell**, run `npx --yes signatureapi init` from the
   application directory, in a background shell. It prints a verification
   URL and a code, then waits. Give both to the user to approve. It then
   writes the test key as `SIGNATUREAPI_KEY` to `.env.local` (Next.js) or
   `.env`. Use `--env-path` and `--var` to match the project. Its result
   names the account as `account.id`. With the MCP connected, compare it
   with `whoami`'s `account.id`. If they differ, the CLI and the MCP act
   for different organizations: stop and ask the user which one to use,
   then run `npx --yes signatureapi logout` and `login` to switch.
   **Without a shell**, ask the user to copy the test key from
   `https://dashboard.signatureapi.com/settings/api-keys` into the env
   file. Name the file and the variable.
3. Confirm the env file is gitignored. Then install the scripts' one
   dependency and check the setup from this skill's directory:

        npm i
        node --env-file=<project env file> scripts/check-setup.mjs

Pass the env file with `--env-file` to every script. Never `cat`, `source`
or `export` it, never ask the user to paste the key, and never put the key
in code, a commit, a log or a command argument. Leave
`SIGNATUREAPI_BASE_URL` and `SIGNATUREAPI_SPEC_URL` unset.

## Start from the design

Classify the request first.

- **A narrow change** (one more place, one more event, a bug): go to Orient
  and Build.
- **One new signing flow, or a change to who signs, how they authenticate
  or who receives email:** get a design brief approved in chat first.
  `signatureapi-architecture` writes it: a few plain lines, one yes. When a
  design document exists, update it instead.
- **A platform-shaped product**, or the user asks for a document. Platform
  means users send their own documents, draw their own fields or send in
  their own name; "a platform like X". The approved design document must
  exist at `docs/signatureapi-integration.md`, or that file must point to
  it. If it does not, run `signatureapi-architecture` first.

Build from what the user approved. Where it is silent on a technical
choice, take the default from the architecture skill's decision matrix and
say so. Keep the user's names for their concepts; SignatureAPI terms belong
at the API boundary. The product shapes a design may name are in
`../signatureapi-architecture/references/product-shapes.md`.

## Orient in this codebase first

Find where signing belongs before writing anything:
`references/brownfield-placement.md`.

## Build

Steps 1–3 prove the flow against the test API. Step 4 is the deliverable.

1. **Get a document URL.** For a throwaway PDF, run
   `node scripts/make-test-document.mjs`. To upload a file while you work,
   use your client's upload tool, or `POST /uploads` with the raw bytes and
   a `Content-Type` header; each returns a temporary `url`. Accepted types,
   the size limit and the URL's lifetime are in
   `node scripts/openapi-explore.mjs operation post /uploads`. For the app's own files, read
   `references/documents.md` first; most failed envelopes come from the
   source file. List the document's bindings and reconcile each one with a
   place or template value, as `references/places.md` describes. Use
   `inspect_upload` to confirm what the service detected.
2. **Create the envelope.** Start from
   `node scripts/create-test-envelope.mjs --dry-run` and adapt it. Every
   place's `recipient_key` must match a recipient's `key`. The script
   defaults to `custom` authentication so verification needs no email;
   `--auth` takes `email_link`, `email_code` or an ordered list:
   `--auth email_link,email_code` keeps SignatureAPI emailing the link and
   adds an emailed code.
   `references/verification-loop.md` explains which method delivers the
   link. Read `references/ceremonies.md` when the flow delivers links
   itself, embeds signing or has several recipients. Keep test titles and
   messages plain: an account may reject URL-, phone- or date-like text
   there. If the design sets `branding.logo`, use the `url` of a permanent
   PNG upload in the same account; the API rejects any other URL,
   including a temporary upload. Upload the PNG with `POST /uploads`, then
   call `POST /uploads/{uploadId}/store` with a unique `key`. Or ask the
   user to upload it in the Dashboard Library and give you its URL.
   Re-run without `--dry-run` to create it. With MCP, pass `mode: "test"`
   to `create_envelope`.
3. **Handle events.** Handle `envelope.completed` for status and
   `deliverable.generated` to fetch the signed file.
   **With a shell**, start the app's handler, then in a background shell:

        npx --yes signatureapi listen --forward-to http://127.0.0.1:<port>/<path>

   Wait for it to report ready. It writes `SIGNATUREAPI_WEBHOOK_ID` and
   `SIGNATUREAPI_WEBHOOK_SECRET` to the env file. Send an example with
   `npx --yes signatureapi trigger envelope.completed` and check the
   handler's own output for a 2xx. Stop the listener when done; that
   disables the endpoint.
   **Without a shell**, or for an endpoint already hosted, register it
   with `create_webhook`. The user copies the signing secret from
   `signing_secret_dashboard_url`. There is no MCP sample-delivery tool:
   create a synthetic test envelope to generate real test events, then
   check delivery with `list_webhook_attempts`.
   `references/webhooks.md` has the verification code and the handler rules.
4. **Write it into the application**, using the codebase's conventions.
   Put the `POST /envelopes` call where the domain action happens. Mount
   the webhook handler on the app's inbound-HTTP path; it verifies the
   signature first. Persist the envelope id on the domain record. Read the key from
   the app's configuration. Re-decide authentication for real recipients
   (`references/verification-loop.md`).

## Verify

The flow is proven when the test envelope reaches `completed`, the events
exist, and the signed file's bytes pass the app's own retrieval and storage
path.

- **Branch A (default):** give the user the ceremony link and wait for them
  to sign. With `custom` authentication the link is in the create response
  (`recipients[].ceremony.url`). With `email_link` it is only in the test
  email: `list_emails`, then `get_email`.
- **Branch B:** when the user asks you to sign, run
  `node --env-file=<project env file> scripts/complete-ceremony.mjs --envelope <id>`.
  It needs Playwright (`npm install --save-dev playwright && npx playwright install chromium`),
  handles signature places only, and refuses a live key.

Then call `list_events` with the `envelope_id` and `wait_seconds: 20`. On
`timed_out`, call it again; do not sleep and poll. Fetch the file with
`get_deliverables`. Without MCP, use `scripts/watch-events.mjs`. Details:
`references/verification-loop.md`.

## Scripts

Run them from this skill's directory with
`node --env-file=<project env file> scripts/<name>`. They print JSON;
failures carry `code`, `message` and `next`.

| Script | Does |
| --- | --- |
| `check-setup.mjs` | Checks the key, its mode and reachability |
| `openapi-explore.mjs` | Reads the contract (Markdown; `--json` for programs) |
| `make-test-document.mjs` | Uploads a throwaway test PDF |
| `create-test-envelope.mjs` | Prints (`--dry-run`) or creates a minimum test envelope |
| `watch-events.mjs` | REST fallback for `list_events` (`--once` for one check) |
| `complete-ceremony.mjs` | Branch B browser walk; test mode only (`--embedded redirect` or `message` also checks the event) |

## References

- `references/brownfield-placement.md` — where signing belongs in an existing codebase
- `references/documents.md` — file sources, DOCX and PDF traps, generated PDFs
- `references/places.md` — how places bind to a document
- `references/ceremonies.md` — link lifecycle, embedding, recipients after creation, live-mode email
- `references/webhooks.md` — registering an endpoint, verification and the handler shape
- `references/verification-loop.md` — both verification branches in full

## Vocabulary

An **envelope** holds **documents** and **recipients**. **Places** are
regions on a document bound to a recipient. Each recipient signs through a
**ceremony**. Completion produces a **deliverable**: the signed documents
plus an audit log.

Referenced files: 15 — file references are metadata, not package contents.

Release notes

SignatureAPI 1.3.0 includes four skills for integration design, implementation, troubleshooting, and documentation research. This submission removes plugin lifecycle hooks, configures the OpenAI review MCP endpoint, and includes five positive and three negative review test cases.

Declared in the saved package. Remote tools may change independently.

Package details

Publisher declarations from the archived package. These are separate from our research and the live service's terms.

Package license
MIT
Package author
Superposition Labs, Inc.
Keywords
See keywords
Review scenarios
5 positive · 3 negativeScenario counts, not test results.

Declared capabilities

  • Interactive
  • Read
  • Write

Package observed Nov 3, 2026.

Technical details
First seen
Nov 3, 2026 · 18:00 UTC
Last seen
Nov 3, 2026 · 18:00 UTC
Collection status
Collected

plugin_asdk_app_6ad8a84c81cc8191b143b974ae0529ac

Download plugin data (JSON)