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

# Bind Link Wallet

> Attach the customer wallet to a link, before or after its review

Binds the wallet a customer will hold their identity with to a link. Your own app calls it when the customer connects a wallet, which can happen before or after the review. The wallet is recorded as bound by you, `walletBoundBy: ISSUER`, and the link accepts no other wallet from then on.

The call binds a wallet only to a link that is not revoked, rejected or consumed. A link past `expiresAt` is refused unless its review was approved: the expiry closes the identity check, not your binding of an approved customer's wallet.

## Before or after the review

**Bound before the review**, nothing else happens yet, and the call answers `registration: AFTER_REVIEW`. An approval later finishes the link with this wallet.

**Bound after an approval** that came without a wallet, `awaitingWallet: true` on [Get ID Link](/endpoints/customers/get-id-link), the link is finished now. From the approval on, this call is the only way to bind the wallet: the hosted page refuses the customer with `409 ISSUER_BINDS_WALLET` and asks them to contact you. Finishing the link does this:

* The customer record is written with the wallet, or created when there is none.
* The wallet's registration on your instance register is queued in the [pending queue](/endpoints/customers/list-pending-verifications) for your wallet to sign, `registration: PENDING`. When your register already verifies the wallet, nothing is queued and the answer is `REGISTERED`.
* When the link's profile has an eligibility register, the wallet's admission to it is queued. See [Eligibility registers](/endpoints/customers/introduction#eligibility-registers).

Nothing is written on chain by this call.

<Note>
  An approved link stays bindable after `expiresAt`, so an approved customer never has to repeat the check. A revoked link is refused with `EXPIRED` at any time.
</Note>

## Path Parameters

<ParamField path="linkId" type="string" required>
  The link `id`, not the token.
</ParamField>

## Body Parameters

<ParamField body="walletAddress" type="string" required>
  The customer's wallet, `0x` followed by 40 hex characters. Stored and returned checksummed. Sending the wallet the link is already bound to is accepted.
</ParamField>

## Response Fields

<ResponseField name="data" type="object">
  <Expandable>
    <ResponseField name="walletAddress" type="string">The bound wallet, checksummed.</ResponseField>
    <ResponseField name="registration" type="string">`AFTER_REVIEW` when the review is still to come, `PENDING` when the registration was queued, `REGISTERED` when your instance register already verifies the wallet.</ResponseField>
    <ResponseField name="customerId" type="string">The customer record written, when the link was finished. Absent with `AFTER_REVIEW`.</ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.trusset.org/customers/api/id-links/cmgdx4r2k0003l50a7c1n8e2w/wallet" \
    -H "Content-Type: application/json" \
    -H "X-API-Key: trusset_your_key_here" \
    -d '{ "walletAddress": "0x96C5822784130360F904372b83E130be4A1894D6" }'
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch(
    'https://api.trusset.org/customers/api/id-links/cmgdx4r2k0003l50a7c1n8e2w/wallet',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': 'trusset_your_key_here'
      },
      body: JSON.stringify({ walletAddress: '0x96C5822784130360F904372b83E130be4A1894D6' })
    }
  );
  const { data } = await response.json();
  ```
</RequestExample>

<ResponseExample>
  ```json Bound After Approval theme={null}
  {
    "success": true,
    "data": {
      "walletAddress": "0x96C5822784130360F904372b83E130be4A1894D6",
      "registration": "PENDING",
      "customerId": "cmgdx5a9q0006l50a2m4k7h1c"
    },
    "error": null,
    "metadata": {
      "requestId": "550e8400-e29b-41d4-a716-446655440000",
      "timestamp": "2026-10-05T10:12:44.000Z"
    }
  }
  ```

  ```json Bound Before Review theme={null}
  {
    "success": true,
    "data": {
      "walletAddress": "0x96C5822784130360F904372b83E130be4A1894D6",
      "registration": "AFTER_REVIEW"
    },
    "error": null,
    "metadata": {
      "requestId": "550e8400-e29b-41d4-a716-446655440000",
      "timestamp": "2026-10-05T09:35:10.000Z"
    }
  }
  ```
</ResponseExample>

## Error Codes

| Code | HTTP | Cause |
| - | - | - |
| `INVALID_ADDRESS` | `400` | `walletAddress` is not a valid address, or is the zero address |
| `EXPIRED` | `400` | The link was revoked, or it is past `expiresAt` and its review was not approved |
| `ALREADY_USED` | `400` | The link is consumed, for example completed on the hosted page or already finished with a wallet |
| `NOT_FOUND` | `404` | No link with this ID exists on your instance |
| `LINK_REJECTED` | `409` | The identity check behind the link was refused, so no wallet can be bound |
| `WALLET_MISMATCH` | `409` | The link is already bound to a different wallet |
| `WALLET_IN_USE` | `409` | The wallet already belongs to another verification on your instance |
| `RATE_LIMIT_EXCEEDED` | `429` | Your instance went over its budget of 120 link onboarding requests per minute |
| `BIND_WALLET_FAILED` | `500` | The wallet could not be bound |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.