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

# Signing modes

> Choose who approves payouts on your non-custodial wallets (people with passkeys, your servers with API keys, or both) and what each mode commits you to.

A non-custodial wallet releases funds only when a signing quorum approves. The customer's **signing mode** decides who on your side can produce those approvals: people with passkeys, your servers with server-held keys, or a mix. This page sets out the three modes and what each one commits you to.

Conduit sets the mode for each customer. New production organizations start in **programmatic**, earlier ones in **passkey required**; sandbox organizations start in **passkey required** (so the [passkey recipes](/sandbox/multi-signer-wallets) work out of the box). To confirm or change a customer's mode, ask your Conduit representative. A customer's wallets keep the mode they were claimed with.

## What never changes

Whichever mode you pick, these hold:

* **Conduit is always a required co-approver.** Reaching your own signing threshold is necessary but never sufficient: Conduit's compliance approval is the final vote on every payout, and it is cast last.
* **Conduit can never move funds without you.** Conduit holds no seat in your signing quorum and cannot reach it alone. Neither side acts alone, in any mode.
* **You hold your private keys.** Conduit receives public keys only. This is true of passkeys and of server keys alike; the custody position is identical in all three modes.
* **At least two administrators.** The [minimum-admin floor](/concepts/signing-thresholds#minimum-admins) on your side of the roster does not change with the mode.
* **No gas to manage.** Network fees are sponsored; the wallet never holds a native-coin balance.

The modes differ in one thing only: **how much of your side of the approval is automatic.**

## The three modes

|                                           | **Passkey required**                                   | **Programmatic** (hybrid)                                                                                                                          | **Programmatic unattended** (fully automatic)  |
| ----------------------------------------- | ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| Who approves payouts                      | People, with passkeys                                  | Your servers, with server-held keys                                                                                                                | Your servers, with server-held keys            |
| Who approves roster and threshold changes | People, with passkeys                                  | People, with passkeys                                                                                                                              | Your servers                                   |
| Human in the loop per payout              | Always                                                 | Optional, never required                                                                                                                           | No                                             |
| How an approval request reaches you       | A `verificationUrl`, per payout, for your approvers    | [`transaction.awaiting_signature`](/webhooks#transactionawaiting_signature) carries a `signingRequestId`; resolve it over the signing-requests API | Same as programmatic                           |
| Administrators                            | Passkey holders                                        | Passkey holders                                                                                                                                    | Server keys allowed                            |
| Enablement                                | Sandbox organizations start here; elsewhere on request | New production organizations start here; otherwise on request                                                                                      | On request, after an additional Conduit review |
| `signingMode` on the webhook              | `passkey_required`                                     | `programmatic`                                                                                                                                     | `programmatic_unattended`                      |

## What each mode commits you to

### Passkey required

Every payout waits on a person. That is the control, and it is also the constraint: each approval attempt has a signing deadline (the `expiresAt` on the [`transaction.awaiting_signature`](/webhooks#transactionawaiting_signature) event; always drive your timers off that value), and a window that lapses without quorum is rebuilt and re-offered a limited number of times before the payout fails. Volume and time-zone coverage are the questions to ask here. This mode suits low-volume, high-value, deliberately reviewed flows.

### Programmatic

Payouts clear at machine speed; changes to *who can sign* still need a human passkey. Two constraints shape your roster:

* **Your machine signers alone must be able to reach the threshold.** A threshold of 2 needs two active machine signers; one machine and one human is refused with `422 PROGRAMMATIC_QUORUM_UNREACHABLE`, both at claim time and on any later roster or threshold change. The rule is about who is *enrolled*, not who approves a given payout: once the roster satisfies it, human passkey signers may stay on the roster and any active signer's approval counts toward quorum.
* **The consequence: a human approval can be possible, but never mandatory.** Your machines can always reach quorum without one, so no threshold setting, customer-wide or per-wallet, can oblige a person to approve. If a mandatory human check is a control you need, enforce it in your own system before your server produces the approval; that is the only place it can bind. Passkey-required is the alternative, but it applies to all of that customer's wallets; it is not a per-wallet carve-out for high-value flows.

A machine signer cannot be an administrator in this mode. Administrators are passkey holders, so governance (adding or removing a signer, changing the threshold) always comes back to a person.

### Programmatic unattended

No human on your side of any decision, including governance. Your key management becomes your control environment: anyone who can use those keys can approve payouts up to your threshold, and can change the roster. Conduit's compliance approval still stands between that and money moving, but nothing on your side does. Because of that, Conduit enables this mode per customer only after an additional approval review; plan for that review before you build against it.

## Operational facts for both programmatic modes

* **You generate the keypair; Conduit gets the public half.** Compressed P-256, 33 bytes. There is no private-key field on any endpoint.
* **Your raw approval signature is never stored.** Conduit relays it and discards it, keeping an audit record of what was signed and which key signed it.
* **A single rejection is terminal.** Any one signer, machine or human, declining a payout ends it. It cannot be revived by another approval.
* **Re-submitting an approval is safe.** A retry returns the request's current state, never a double count. The approve and reject calls require an `Idempotency-Key` header: a missing key is refused with `400`, and reusing a key with a different body returns `409`.
* **Approval windows expire.** If a window lapses before quorum, the request is rebuilt with a new `signingRequestId` and your servers must stamp the new one. Handle the second webhook, not just the first.
* **Containment is add-then-remove, not a setting.** If a key is compromised, seat a replacement machine signer first, then remove the compromised one; each step is a governance change under an admin approval. A removal that would leave the machine keys unable to reach the threshold is refused (`422 PROGRAMMATIC_QUORUM_UNREACHABLE`, or `403 SIGNER_REMOVAL_FORBIDDEN` when the machine signers are the whole roster), and the minimum roster (machine signers = threshold) is always in that position, so add first. Once the removal is accepted, that key's signatures stop being accepted immediately. Changing the signing mode does not deactivate a live machine signer; planned key rotation is the same add-then-remove sequence.

The signing loop itself (generate the key, register it, discover requests, stamp them) is in [Programmatic payout signing](/guides/machine-signer-stamping).

## Which mode fits

* Need a person to see every payout: **passkey required**.
* Need payouts to clear without waiting on a person, but want people to control who can sign: **programmatic**.
* Need a signing path with no human step at all, and can evidence the key controls to justify it: **programmatic unattended**.

The mode is fixed for each customer at claim time, so decide before the customer claims. A mode change arranged with Conduit applies to customers who claim after it; for a customer that has already claimed, talk to your Conduit representative.

## Related

<CardGroup cols={2}>
  <Card title="Programmatic payout signing" href="/guides/machine-signer-stamping">
    The machine signing loop: generate a key, register it, stamp requests.
  </Card>

  <Card title="Multi-signer wallets" href="/concepts/multi-signer-wallets">
    Roster rules, admins, ceremonies, and lifecycle endpoints.
  </Card>

  <Card title="Signing thresholds" href="/concepts/signing-thresholds">
    M-of-N thresholds, the minimum-admin floor, per-wallet overrides.
  </Card>

  <Card title="Non-Custodial Wallets" href="/concepts/non-custodial-wallets">
    The two-signature model and the hosted verify page.
  </Card>
</CardGroup>
