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

# Order API: create, track, and pay sign/notarize/ship orders

> Create sign, notarize, and ship orders for your clients' own completed documents, list and fetch them, and mint Stripe hosted checkout — priced server-side with your partner discount.

The Order API places a full SignSealShip order — e-signing, online notarization, shipping, in any combination — for a document your client has already completed. You send the PDF (or a fill-online token) plus the services; SignSealShip prices the order server-side from the B2B price book with your subscription tier's discount applied automatically, and returns an itemized quote. There is no client-sent amount anywhere in the API.

Payment goes through Stripe hosted checkout: mint the checkout URL at create time with `create_checkout=true`, or later with the [checkout endpoint](#mint-a-checkout-session), and hand it to whoever pays.

<Note>
  **Order state advances only via the verified Stripe webhook.** Minting a
  checkout session never changes state, and neither does a payer landing on
  the success page — SignSealShip marks an order paid only when Stripe's
  signed webhook confirms it. Poll [`GET
      /api/partner/orders/{code}`](#fetch-an-order) or subscribe to the
  [order webhook topics](/api-reference/webhooks) to follow along.
</Note>

All four routes require your key (`Authorization: Bearer sss_pk_...`) and share the `partner-write` limit of 60 requests per minute per key. See [authentication](/api-reference/authentication).

## Create an order

`POST /api/partner/orders`

The request is `multipart/form-data`. Send the document exactly one of two ways — never both:

* **Upload it** as the `document` part (PDF, up to 35 MB), or
* **Reference a fill-online result** with `fill_token`, the 40-character lowercase-hex token the fill-online rail hands back after your client types through a form.

<ParamField body="document" type="file">
  The client's own completed PDF, up to 35 MB. Mutually exclusive with
  `fill_token`.
</ParamField>

<ParamField body="fill_token" type="string">
  A 40-character lowercase-hex token from the fill-online rail, in place of a
  `document` upload. Mutually exclusive with `document`.
</ParamField>

<ParamField body="email" type="string" required>
  The signer / client email.
</ParamField>

<ParamField body="name" type="string">
  The signer / client name.
</ParamField>

<ParamField body="doc_slug" type="string">
  A catalog document slug (see the [Forms & Documents
  library](https://signsealship.com/forms)). When present, the catalog row
  defines the sign / notary services for the order; shipping stays additive
  via `svc_ship`.
</ParamField>

<ParamField body="svc_sign" type="string">
  `"true"` to include e-signing.
</ParamField>

<ParamField body="svc_notary" type="string">
  `"true"` to include online notarization.
</ParamField>

<ParamField body="svc_ship" type="string">
  `"true"` to include shipping. Send the `ship_*` address fields with it.
</ParamField>

<ParamField body="signer_state" type="string">
  Two-letter US state where the signer is located.
</ParamField>

<ParamField body="dest_state" type="string">
  Two-letter US state the shipment is destined for.
</ParamField>

<ParamField body="byod_confirmed" type="string" required>
  Must be `"true"` — attests that this is the client's own completed document
  (bring-your-own-document).
</ParamField>

<ParamField body="external_reference" type="string">
  Your own matter / file number, up to 120 characters. Echoed back on
  listings, the fetch endpoint, and every [order webhook
  event](/api-reference/webhooks#order-events), so you can correlate without
  storing order codes.
</ParamField>

<ParamField body="ship_name" type="string">
  Recipient name, when shipping. `ship_line1`, `ship_line2`, `ship_city`,
  `ship_state`, and `ship_postal` complete the address the same way.
</ParamField>

<ParamField body="create_checkout" type="string">
  `"true"` to also mint the Stripe hosted-checkout session in the same call
  and return it as `checkoutUrl`.
</ParamField>

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://signsealship.com/api/partner/orders \
    -H "Authorization: Bearer sss_pk_your_key" \
    -F "document=@deed-package.pdf" \
    -F "email=client@example.com" \
    -F "name=Dana Reyes" \
    -F "svc_sign=true" \
    -F "svc_notary=true" \
    -F "svc_ship=true" \
    -F "signer_state=NJ" \
    -F "dest_state=CA" \
    -F "byod_confirmed=true" \
    -F "external_reference=MATTER-2291" \
    -F "ship_name=Dana Reyes" \
    -F "ship_line1=1428 Maple St" \
    -F "ship_city=Sacramento" \
    -F "ship_state=CA" \
    -F "ship_postal=95814" \
    -F "create_checkout=true"
  ```

  ```javascript Node theme={null}
  import { readFile } from "node:fs/promises";

  const form = new FormData();
  form.set(
    "document",
    new Blob([await readFile("deed-package.pdf")], { type: "application/pdf" }),
    "deed-package.pdf",
  );
  form.set("email", "client@example.com");
  form.set("name", "Dana Reyes");
  form.set("svc_sign", "true");
  form.set("svc_notary", "true");
  form.set("byod_confirmed", "true");
  form.set("external_reference", "MATTER-2291");
  form.set("create_checkout", "true");

  const res = await fetch("https://signsealship.com/api/partner/orders", {
    method: "POST",
    headers: { Authorization: `Bearer ${process.env.SSS_PARTNER_KEY}` },
    body: form,
  });
  const order = await res.json(); // 201
  console.log(order.orderCode, order.totalCents, order.checkoutUrl);
  ```

  ```python Python theme={null}
  import os
  import requests

  res = requests.post(
      "https://signsealship.com/api/partner/orders",
      headers={"Authorization": f"Bearer {os.environ['SSS_PARTNER_KEY']}"},
      files={"document": ("deed-package.pdf", open("deed-package.pdf", "rb"), "application/pdf")},
      data={
          "email": "client@example.com",
          "name": "Dana Reyes",
          "svc_sign": "true",
          "svc_notary": "true",
          "byod_confirmed": "true",
          "external_reference": "MATTER-2291",
          "create_checkout": "true",
      },
  )
  order = res.json()  # 201
  print(order["orderCode"], order["totalCents"], order["checkoutUrl"])
  ```
</CodeGroup>

<ResponseField name="orderCode" type="string">
  The order's public code — the same code that opens `/orders/{orderCode}`
  and that [rooms attach by](/api-reference/rooms#attach-an-order).
</ResponseField>

<ResponseField name="orderUrl" type="string">
  Root-relative path to the order page, `/orders/{orderCode}`.
</ResponseField>

<ResponseField name="status" type="string">
  The order's status name (for example `"QuoteReady"`).
</ResponseField>

<ResponseField name="externalReference" type="string">
  The `external_reference` you sent, or `null`.
</ResponseField>

<ResponseField name="subtotalCents" type="integer">
  Pre-discount total in USD cents, from the B2B price book.
</ResponseField>

<ResponseField name="discountCents" type="integer">
  Your subscription-tier discount, computed and applied server-side.
</ResponseField>

<ResponseField name="totalCents" type="integer">
  What checkout will charge: `subtotalCents - discountCents`.
</ResponseField>

<ResponseField name="lines" type="array">
  The itemized quote.

  <Expandable title="line">
    <ResponseField name="type" type="string">
      Machine-readable line type.
    </ResponseField>

    <ResponseField name="label" type="string">
      Display label for the line.
    </ResponseField>

    <ResponseField name="amountCents" type="integer">
      Line amount in USD cents.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="checkoutUrl" type="string">
  The Stripe hosted-checkout URL. `null` unless all three hold:
  `create_checkout=true` was sent, payments are configured, and the order is
  payable — an order that needs a manual quote (`ManualQuoteRequired`)
  returns no checkout.
</ResponseField>

```json 201 Created theme={null}
{
  "orderCode": "an-order-public-code",
  "orderUrl": "/orders/an-order-public-code",
  "status": "QuoteReady",
  "externalReference": "MATTER-2291",
  "subtotalCents": 7635,
  "discountCents": 500,
  "totalCents": 7135,
  "lines": [
    { "type": "WorkflowFee", "label": "Document workflow", "amountCents": 1200 },
    { "type": "NotaryFee", "label": "Online notarization", "amountCents": 2500 },
    { "type": "ShippingCarrierRate", "label": "Carrier postage (rated for your address)", "amountCents": 2440 },
    { "type": "ShippingHandlingFee", "label": "Shipping & handling", "amountCents": 1495 },
    { "type": "Discount", "label": "Code WELCOME5", "amountCents": -500 }
  ],
  "checkoutUrl": "https://checkout.stripe.com/c/pay/cs_live_..."
}
```

Line `type` values are the PascalCase names of the platform's line-type enum
(`WorkflowFee`, `NotaryFee`, `TechFee`, `RushFee`, `ExtraSignerFee`,
`ExtraSealFee`, `WitnessFee`, `ScanbackFee`, `StorageFee`,
`ShippingCarrierRate`, `ShippingHandlingFee`, `PrintMailFee`, `FaxFee`,
`ServiceAdjustment`, `Discount`, …). Worth coding against:

* **There is no `esign` line.** E-signature retail is folded into `WorkflowFee`.
* **Shipping is TWO lines** since live rate-shopping shipped: the carrier's
  postage passed through at the rate quoted for the destination address
  (`ShippingCarrierRate`), plus a disclosed handling fee
  (`ShippingHandlingFee`). Postage varies by address — it is no longer a flat
  amount you can predict from the request alone.
* **Discount codes appear as a negative-amount `Discount` line.**
* New types may be added over time; render unknown types as display-only rows.

Errors: `400` `{"error": "..."}` for validation failures and blocked states — a missing `email` or `byod_confirmed`, both `document` and `fill_token` (or neither), an oversized file, a bad `fill_token`, or an unknown `doc_slug`. `401` `{"error": "..."}` for a missing or bad key.

## List your orders

`GET /api/partner/orders?limit=&status=&external_reference=`

Returns the orders created with your partner key, newest first.

<ParamField query="limit" type="integer" default="20">
  Page size — default 20, maximum 100.
</ParamField>

<ParamField query="status" type="string">
  Filter by order status name (for example `QuoteReady`, `Paid`,
  `Completed`).
</ParamField>

<ParamField query="external_reference" type="string">
  Filter to orders created with this `external_reference`.
</ParamField>

<CodeGroup>
  ```bash curl theme={null}
  curl "https://signsealship.com/api/partner/orders?status=Paid&limit=50" \
    -H "Authorization: Bearer sss_pk_your_key"
  ```

  ```javascript Node theme={null}
  const res = await fetch(
    "https://signsealship.com/api/partner/orders?external_reference=MATTER-2291",
    { headers: { Authorization: `Bearer ${process.env.SSS_PARTNER_KEY}` } },
  );
  const { orders } = await res.json();
  ```

  ```python Python theme={null}
  import os
  import requests

  orders = requests.get(
      "https://signsealship.com/api/partner/orders",
      headers={"Authorization": f"Bearer {os.environ['SSS_PARTNER_KEY']}"},
      params={"status": "Paid", "limit": 50},
  ).json()["orders"]
  ```
</CodeGroup>

<ResponseField name="orders" type="array">
  One summary per order, newest first.

  <Expandable title="order summary">
    <ResponseField name="orderCode" type="string">
      The order's public code.
    </ResponseField>

    <ResponseField name="status" type="string">
      The order's status name.
    </ResponseField>

    <ResponseField name="services" type="string">
      Which services the order includes, as a comma-separated flags string —
      e.g. `"Sign"`, `"Sign, Notarize"`, `"Sign, Notarize, Ship"`,
      `"Fax"`. Possible flags: `Sign`, `Notarize`, `Ship`, `Fax`. Parse by
      splitting on `", "` — this is NOT an object of booleans.
    </ResponseField>

    <ResponseField name="totalCents" type="integer">
      Order total in USD cents, discount already applied.
    </ResponseField>

    <ResponseField name="externalReference" type="string">
      Your reference, or `null`.
    </ResponseField>

    <ResponseField name="customerEmail" type="string">
      The signer / client email from the create call.
    </ResponseField>

    <ResponseField name="createdAt" type="string">
      ISO 8601 creation time.
    </ResponseField>
  </Expandable>
</ResponseField>

## Fetch an order

`GET /api/partner/orders/{code}`

Partner-scoped: another partner's order and an unknown code return the identical `404` — nothing to enumerate.

<ParamField path="code" type="string" required>
  The order's public code from the create response.
</ParamField>

<CodeGroup>
  ```bash curl theme={null}
  curl https://signsealship.com/api/partner/orders/{code} \
    -H "Authorization: Bearer sss_pk_your_key"
  ```

  ```javascript Node theme={null}
  const res = await fetch(
    `https://signsealship.com/api/partner/orders/${code}`,
    { headers: { Authorization: `Bearer ${process.env.SSS_PARTNER_KEY}` } },
  );
  if (res.ok) {
    const order = await res.json();
    console.log(order.status, order.envelopeStatus);
  }
  ```

  ```python Python theme={null}
  import os
  import requests

  res = requests.get(
      f"https://signsealship.com/api/partner/orders/{code}",
      headers={"Authorization": f"Bearer {os.environ['SSS_PARTNER_KEY']}"},
  )
  if res.ok:
      order = res.json()
      print(order["status"], order["envelopeStatus"])
  ```
</CodeGroup>

The response carries everything the create response does — `orderCode`, `orderUrl`, `status`, `externalReference`, `subtotalCents`, `discountCents`, `totalCents`, `lines` — plus:

<ResponseField name="services" type="string">
  Which services the order includes, as a comma-separated flags string — e.g.
  `"Sign, Notarize, Ship"`. Possible flags: `Sign`, `Notarize`, `Ship`, `Fax`.
  Parse by splitting on `", "` — this is NOT an object of booleans.
</ResponseField>

<ResponseField name="envelopeStatus" type="string">
  The e-sign envelope's status once the order includes signing, or `null`.
</ResponseField>

<ResponseField name="customerEmail" type="string">
  The signer / client email.
</ResponseField>

<ResponseField name="createdAt" type="string">
  ISO 8601 creation time.
</ResponseField>

Errors: `404` `{"error": "..."}` for an unknown code or another partner's order — indistinguishable by design.

## Mint a checkout session

`POST /api/partner/orders/{code}/checkout`

Mint the Stripe hosted-checkout URL for a payable order — the same URL `create_checkout=true` returns at create time. Use it when you quoted first and collect payment later.

<ParamField path="code" type="string" required>
  The order's public code.
</ParamField>

```bash curl theme={null}
curl -X POST https://signsealship.com/api/partner/orders/{code}/checkout \
  -H "Authorization: Bearer sss_pk_your_key"
```

```json 200 OK theme={null}
{ "checkoutUrl": "https://checkout.stripe.com/c/pay/cs_live_..." }
```

Errors: `404` for an unknown or cross-partner code, `409` `{"error": "..."}` when the order is not payable in its current state (for example, awaiting a manual quote), `503` `{"error": "..."}` when payments are not configured, `502` `{"error": "..."}` when Stripe fails to create the session.

<Check>
  Orders created through this API emit `order.created`, `payment.cleared`,
  `signature.completed`, and `shipment.delivered` events to subscribed
  webhooks, each echoing your `external_reference` — see
  [webhooks](/api-reference/webhooks#order-events).
</Check>
