> ## 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.

# Build Pending Registration

> Unsigned transactions that register queued KYC approvals on your register

Returns the unsigned transactions that register a set of rows from [List Pending Verifications](/endpoints/customers/list-pending-verifications). They carry what was queued: the `kycHash`, investor type, expiries and residency claim the platform computed at approval. Your wallets sign and broadcast them, then [Confirm Pending Registration](/endpoints/customers/confirm-pending-registration) records the result.

What comes back depends on the register your instance writes to, reported as `registerKind`. A Trusset register takes one batch. An ERC-3643 register takes up to three phases of signatures, so call again after each until `phase` is `REGISTER`.

<Warning>
  One row from a blocked country refuses the whole call with `COUNTRY_BLOCKED`, and the message names its wallet. Leave that id out to build the rest. Dismissing the row also lets the rest build, but a dismissal cannot be undone. A dismissed approval never reaches the register from the queue.

  On a Trusset register the batch skips some entries without reverting. It skips a wallet that already holds an unrevoked identity, a row whose expiry has passed, and any entry it runs out of gas for. Read what the confirm then does on [Confirm Pending Registration](/endpoints/customers/confirm-pending-registration) before building rows for wallets that were verified before.
</Warning>

## Body Parameters

<ParamField body="ids" type="array" required>
  1 to 200 row ids. Only rows still `PENDING` on your instance are used, and any other id is dropped without an error. Compare `ids` in the response with what you sent.
</ParamField>

<ParamField body="claimSignatures" type="array">
  ERC-3643 only. The signatures from the `SIGN_CLAIMS` phase, as `[{ walletAddress, signature, claimType }]`. Name `claimType` on each. Without it a signature matches only a wallet with a single claim to sign, and an unmatched signature is no error: the call answers `SIGN_CLAIMS` again.
</ParamField>

<ParamField body="signerAddress" type="string">
  ERC-3643 only. The wallet that will sign the claims. It must hold a CLAIM key on the register's trusted issuer. Otherwise the call is refused with `CLAIM_SIGNER_NOT_TRUSTED`, or with `CLAIM_SIGNER_MISSING` when none of your registered wallets holds one either. It also becomes the management key of every ONCHAINID the plan deploys. Name a wallet registered to your instance, because [Confirm ONCHAINID](/endpoints/customers/confirm-onchainid) refuses any other management key. Omit it to use the first registered wallet that holds a CLAIM key. A malformed address is ignored.
</ParamField>

## Sign for a Trusset register

The answer is `SIGN_TRANSACTIONS` with `registerKind` set to `TRUSSET`. The first step is one `batchVerifyIdentities` call for every row. Each row with a `residencyClaim` adds an `addClaim` step that files its `RESIDENCY` slot.

Sign every step with a wallet registered to your instance that holds `KYC_PROVIDER_ROLE` on the register. The build refuses with `KYC_PROVIDER_ROLE_MISSING` when the register reports that none of your registered wallets holds it.

Broadcast the steps in order, and let the batch be mined before the claims. The register refuses a claim for an identity that is not active yet.

Confirm with the batch hash as `txHash` and each claim hash in `claimTxResults`.

## Sign for an ERC-3643 register

An ERC-3643 register looks up an identity contract per wallet, the ONCHAINID, and the claims on it. A registration needs the identity, a signed claim and a register entry, so the answer comes in phases. Send the same `ids` each time, with what the previous phase produced.

<Steps>
  <Step title="DEPLOY_IDENTITY">
    `action` is `SIGN_TRANSACTIONS`, returned while any wallet in the batch has no ONCHAINID. Each step is a contract creation that deploys an ONCHAINID with `signerAddress` as its management key. Broadcast each one from any wallet, record it with [Confirm ONCHAINID](/endpoints/customers/confirm-onchainid) using the step's `walletAddress` and the hash, then call again.
  </Step>

  <Step title="SIGN_CLAIMS">
    `action` is `SIGN_MESSAGES`, returned while a claim has no signature. Sign each `messageHash` as an EIP-191 personal message with a wallet that holds a CLAIM key (purpose 3) on `claimIssuer`. Call again with the results in `claimSignatures`. Each one is checked against the trusted issuer before any step is built.
  </Step>

  <Step title="REGISTER">
    `action` is `SIGN_TRANSACTIONS`. The steps are one `addClaim` per claim, then `registerIdentity` or `batchRegisterIdentity` for wallets not yet on the register, then `updateCountry` for registered wallets whose country differs. Broadcast them in order.
  </Step>
</Steps>

Each `addClaim` step calls the customer's ONCHAINID, so send it from that identity's management key. For an identity deployed through this API, that is the `managementKey` its deployment named, which in this flow is `signerAddress`.

The register and country steps must come from an agent of the register. The build refuses with `REGISTRY_AGENT_MISSING` when the register reports that none of your registered wallets is one.

Confirm with the register step's hash as `txHash` and every claim step's hash in `claimTxResults`. When every wallet was already registered there is no register step, so send `claimTxResults` alone. Country steps need no hash.

An ERC-3643 register stores no investor type and no expiry, so the row's `investorType`, `softExpiry` and `hardExpiry` are not written anywhere. The country is written as its ISO 3166-1 numeric code, and a row without one registers with `0`.

The KYC claim is filed under `claimTopic`, the first required topic that one of your wallets can sign for. A register that requires further topics does not report the wallet as verified, and its row stays queued at confirm.

This endpoint takes no `identities` field. It finds an ONCHAINID on the register itself, or through [Confirm ONCHAINID](/endpoints/customers/confirm-onchainid), which records only a deployment this API planned.

## Response Fields

<ResponseField name="data" type="object">
  <Expandable>
    <ResponseField name="action" type="string">`SIGN_TRANSACTIONS`, or `SIGN_MESSAGES` in the `SIGN_CLAIMS` phase.</ResponseField>
    <ResponseField name="registerKind" type="string">`TRUSSET` or `TREX`.</ResponseField>
    <ResponseField name="phase" type="string">ERC-3643 only. `DEPLOY_IDENTITY`, `SIGN_CLAIMS` or `REGISTER`.</ResponseField>
    <ResponseField name="steps" type="array">The unsigned transactions, in order. See below. Absent in the `SIGN_CLAIMS` phase.</ResponseField>
    <ResponseField name="messages" type="array">`SIGN_CLAIMS` only. Per claim: `walletAddress`, `identity`, `topic`, `claimIssuer`, `data`, `messageHash`, `scheme` (`eip191`), `description` and `claimType`.</ResponseField>
    <ResponseField name="total" type="integer">Rows used.</ResponseField>
    <ResponseField name="ids" type="array">The ids of the rows used. Send these to the confirm.</ResponseField>
    <ResponseField name="rows" type="array">ERC-3643 only. Per row: `id`, `walletAddress`, and `identity`, the ONCHAINID found for it or `null`.</ResponseField>
    <ResponseField name="register" type="string">ERC-3643 only. The register address.</ResponseField>
    <ResponseField name="signerAddress" type="string">ERC-3643 only. The claim signer, which is also the management key of every ONCHAINID the plan deploys.</ResponseField>
    <ResponseField name="claimSigners" type="array">ERC-3643 only. The wallets, among `signerAddress` and your registered wallets, that hold a CLAIM key on `claimIssuer`.</ResponseField>
    <ResponseField name="claimIssuer" type="string">ERC-3643 only. The trusted issuer the claims are signed for.</ResponseField>
    <ResponseField name="claimTopic" type="string">ERC-3643 only. The KYC claim topic, as a decimal string.</ResponseField>
    <ResponseField name="identities" type="object">ERC-3643 only. The ONCHAINID of each wallet that has one, keyed by checksummed wallet.</ResponseField>
    <ResponseField name="next" type="string">`DEPLOY_IDENTITY` and `SIGN_CLAIMS` only. What to do next, in words.</ResponseField>
    <ResponseField name="confirmStepIndex" type="integer">`REGISTER` only. Index of the register step, or of the last step when there is none.</ResponseField>
    <ResponseField name="registerStep" type="string">`REGISTER` only. `registerIdentity` whenever the steps include a register call, `batchRegisterIdentity` included, otherwise `null`.</ResponseField>
    <ResponseField name="description" type="string">`REGISTER` only. A summary of the registration.</ResponseField>
    <ResponseField name="confirmWith" type="object">Where the next hash goes, as `endpoint` and `fields`. It names Confirm ONCHAINID in the `DEPLOY_IDENTITY` phase and Confirm Pending Registration once there are steps to confirm. It is `null` in `SIGN_CLAIMS`.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="steps" type="array">
  <Expandable>
    <ResponseField name="action" type="string">`SIGN_TRANSACTION`.</ResponseField>
    <ResponseField name="stepType" type="string">`verify` for the batch or register call, `residencyClaim` or `claim` for a claim, `country` for `updateCountry`, and `deployIdentity` for an ONCHAINID.</ResponseField>
    <ResponseField name="transaction" type="object">`to` and `data`. A deployment has `to: null` and `create: true`, and is sent as a contract creation.</ResponseField>
    <ResponseField name="functionName" type="string">`batchVerifyIdentities`, `addClaim`, `registerIdentity`, `batchRegisterIdentity` or `updateCountry`, or `IdentityProxy` for a deployment.</ResponseField>
    <ResponseField name="description" type="string">What the step does.</ResponseField>
    <ResponseField name="ids" type="array">The rows a batch or register step covers.</ResponseField>
    <ResponseField name="id" type="string">The row a claim or country step belongs to. Send a claim step's hash under it in `claimTxResults`.</ResponseField>
    <ResponseField name="walletAddress" type="string">ERC-3643 only. The customer's wallet. A `batchRegisterIdentity` step lists them in `walletAddresses` instead.</ResponseField>
    <ResponseField name="identity" type="string">ERC-3643 claim steps. The ONCHAINID the claim is added to.</ResponseField>
    <ResponseField name="claimType" type="string">ERC-3643 claim steps. `KYC` or `RESIDENCY`.</ResponseField>
    <ResponseField name="dataHash" type="string">ERC-3643 claim steps. The claim data.</ResponseField>
    <ResponseField name="managementKey" type="string">Deployments. The management key the ONCHAINID is created with.</ResponseField>
    <ResponseField name="implementationAuthority" type="string">Deployments. The implementation authority the ONCHAINID proxies to.</ResponseField>
  </Expandable>
</ResponseField>

## Drive both registers

The example uses one issuer wallet, `wallet`, as an ethers v5 signer. On an ERC-3643 register it assumes that wallet is an agent of the register and holds a CLAIM key on its trusted issuer. Passing its address as `signerAddress` makes it the management key of any ONCHAINID it deploys, so it can also send the claim steps.

On a Trusset register the first answer has no `phase`, so the loop is skipped and the steps are broadcast directly.

```typescript theme={null}
import { ethers } from 'ethers';

const api = 'https://api.trusset.org/customers/api/identity';
const headers = { 'X-API-Key': 'trusset_your_key_here', 'Content-Type': 'application/json' };

const post = async (path: string, body: object) => {
  const res = await fetch(`${api}${path}`, { method: 'POST', headers, body: JSON.stringify(body) });
  const json = await res.json();
  if (!json.success) throw new Error(`${json.error.code}: ${json.error.message}`);
  return json.data;
};

const ids = ['cmg1u7k3p0004l80h2f9s6d1x', 'cmg1u9q2m0007l80hc4t8z3wa'];
const signerAddress = await wallet.getAddress();
const claimSignatures: { walletAddress: string; signature: string; claimType: string }[] = [];

let plan = await post('/pending/calldata', { ids, signerAddress });

while (plan.phase === 'DEPLOY_IDENTITY' || plan.phase === 'SIGN_CLAIMS') {
  if (plan.phase === 'DEPLOY_IDENTITY') {
    for (const step of plan.steps) {
      const tx = await wallet.sendTransaction({ data: step.transaction.data });
      await tx.wait();
      await post('/onchainid/confirm', { walletAddress: step.walletAddress, txHash: tx.hash });
    }
  } else {
    for (const message of plan.messages) {
      const signature = await wallet.signMessage(ethers.utils.arrayify(message.messageHash));
      claimSignatures.push({ walletAddress: message.walletAddress, signature, claimType: message.claimType });
    }
  }
  plan = await post('/pending/calldata', { ids, signerAddress, claimSignatures });
}

let txHash: string | undefined;
const claimTxResults: { id: string; txHash: string }[] = [];

for (const step of plan.steps) {
  const tx = await wallet.sendTransaction(step.transaction);
  await tx.wait();
  if (step.functionName === 'addClaim') claimTxResults.push({ id: step.id, txHash: tx.hash });
  if (step.stepType === 'verify') txHash = tx.hash;
}

const result = await post('/pending/confirm', { ids: plan.ids, txHash, claimTxResults });
```

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.trusset.org/customers/api/identity/pending/calldata" \
    -H "X-API-Key: trusset_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "ids": ["cmg1u7k3p0004l80h2f9s6d1x", "cmg1u9q2m0007l80hc4t8z3wa"],
      "signerAddress": "0xCD92134767aEC2562be15d2a2062A082dA17dD84"
    }'
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch(
    'https://api.trusset.org/customers/api/identity/pending/calldata',
    {
      method: 'POST',
      headers: { 'X-API-Key': 'trusset_your_key_here', 'Content-Type': 'application/json' },
      body: JSON.stringify({
        ids: ['cmg1u7k3p0004l80h2f9s6d1x', 'cmg1u9q2m0007l80hc4t8z3wa'],
        signerAddress: '0xCD92134767aEC2562be15d2a2062A082dA17dD84'
      })
    }
  );

  const { data: plan } = await response.json();
  ```
</RequestExample>

<ResponseExample>
  ```json Trusset Register theme={null}
  {
    "success": true,
    "data": {
      "action": "SIGN_TRANSACTIONS",
      "registerKind": "TRUSSET",
      "steps": [
        {
          "action": "SIGN_TRANSACTION",
          "transaction": {
            "to": "0xBC06fBe06A95aC37425A3736Dd862de129a9E100",
            "data": "0x9f4cc990..."
          },
          "functionName": "batchVerifyIdentities",
          "description": "Register 2 verified identities on-chain",
          "stepType": "verify",
          "ids": ["cmg1u7k3p0004l80h2f9s6d1x", "cmg1u9q2m0007l80hc4t8z3wa"]
        },
        {
          "action": "SIGN_TRANSACTION",
          "transaction": {
            "to": "0xBC06fBe06A95aC37425A3736Dd862de129a9E100",
            "data": "0x07363788..."
          },
          "functionName": "addClaim",
          "description": "Add residency claim for 0x96c5822784130360f904372b83e130be4a1894d6",
          "stepType": "residencyClaim",
          "id": "cmg1u7k3p0004l80h2f9s6d1x"
        },
        {
          "action": "SIGN_TRANSACTION",
          "transaction": {
            "to": "0xBC06fBe06A95aC37425A3736Dd862de129a9E100",
            "data": "0x07363788..."
          },
          "functionName": "addClaim",
          "description": "Add residency claim for 0xff21b8ac28bb6a20c1c0160af42303d2946b99ea",
          "stepType": "residencyClaim",
          "id": "cmg1u9q2m0007l80hc4t8z3wa"
        }
      ],
      "total": 2,
      "ids": ["cmg1u7k3p0004l80h2f9s6d1x", "cmg1u9q2m0007l80hc4t8z3wa"],
      "confirmWith": {
        "endpoint": "POST /customers/api/identity/pending/confirm",
        "fields": ["ids", "txHash", "claimTxResults?"]
      }
    },
    "error": null,
    "metadata": {
      "requestId": "550e8400-e29b-41d4-a716-446655440000",
      "timestamp": "2026-09-30T10:00:00.000Z"
    }
  }
  ```

  ```json ERC-3643 Deploy Phase theme={null}
  {
    "success": true,
    "data": {
      "register": "0xc9B421D7403A4eAfCC4ba5FE38E98691BAdBFa0E",
      "registerKind": "TREX",
      "signerAddress": "0xCD92134767aEC2562be15d2a2062A082dA17dD84",
      "claimSigners": ["0xCD92134767aEC2562be15d2a2062A082dA17dD84"],
      "action": "SIGN_TRANSACTIONS",
      "phase": "DEPLOY_IDENTITY",
      "steps": [
        {
          "action": "SIGN_TRANSACTION",
          "stepType": "deployIdentity",
          "walletAddress": "0x96C5822784130360F904372b83E130be4A1894D6",
          "managementKey": "0xCD92134767aEC2562be15d2a2062A082dA17dD84",
          "implementationAuthority": "0x77B26Fa7a8a7907134c56c83a56728Fb7C839FbD",
          "transaction": {
            "to": null,
            "data": "0x608060405234801561001057600080fd5b50...",
            "create": true
          },
          "functionName": "IdentityProxy",
          "description": "Deploy the ONCHAINID identity contract for 0x96C5822784130360F904372b83E130be4A1894D6 (management key 0xCD92134767aEC2562be15d2a2062A082dA17dD84)"
        }
      ],
      "identities": {},
      "claimIssuer": "0xbacb9739Dd6D129B04d7Fc5B5c426c33429cC4E2",
      "claimTopic": "109015029463275868683647211611771110530627425002451180747115609001006883683411",
      "next": "Sign each deployment, confirm it with POST /identity/onchainid/confirm {walletAddress, txHash} so the ONCHAINID is recorded, then repeat this call.",
      "confirmWith": {
        "endpoint": "POST /customers/api/identity/onchainid/confirm",
        "fields": ["walletAddress", "txHash"]
      },
      "total": 1,
      "ids": ["cmg1u7k3p0004l80h2f9s6d1x"],
      "rows": [
        { "id": "cmg1u7k3p0004l80h2f9s6d1x", "walletAddress": "0x96c5822784130360f904372b83e130be4a1894d6", "identity": null }
      ]
    },
    "error": null,
    "metadata": {
      "requestId": "550e8400-e29b-41d4-a716-446655440000",
      "timestamp": "2026-09-30T10:00:00.000Z"
    }
  }
  ```

  ```json ERC-3643 Sign Phase theme={null}
  {
    "success": true,
    "data": {
      "register": "0xc9B421D7403A4eAfCC4ba5FE38E98691BAdBFa0E",
      "registerKind": "TREX",
      "signerAddress": "0xCD92134767aEC2562be15d2a2062A082dA17dD84",
      "claimSigners": ["0xCD92134767aEC2562be15d2a2062A082dA17dD84"],
      "action": "SIGN_MESSAGES",
      "phase": "SIGN_CLAIMS",
      "messages": [
        {
          "walletAddress": "0x96C5822784130360F904372b83E130be4A1894D6",
          "identity": "0x8986b6a837ccA6c6F6e257526296f07b9fe3fA9f",
          "topic": "109015029463275868683647211611771110530627425002451180747115609001006883683411",
          "claimIssuer": "0xbacb9739Dd6D129B04d7Fc5B5c426c33429cC4E2",
          "data": "0xd815320690e956adfd07197c275b560561fbf5aab2d633d3d46db748c468d0af",
          "messageHash": "0xd094a5d1f2f998f5e5387a9566b2851874d9dcfbd77488604eea418c1e67f510",
          "scheme": "eip191",
          "description": "Sign keccak256(abi.encode(identity, topic, data)) as an EIP-191 personal message with a wallet that holds a CLAIM key on 0xbacb9739Dd6D129B04d7Fc5B5c426c33429cC4E2",
          "claimType": "KYC"
        },
        {
          "walletAddress": "0x96C5822784130360F904372b83E130be4A1894D6",
          "identity": "0x8986b6a837ccA6c6F6e257526296f07b9fe3fA9f",
          "topic": "91459909311584976962361246790355186201871734689447147205462650852954438227679",
          "claimIssuer": "0xbacb9739Dd6D129B04d7Fc5B5c426c33429cC4E2",
          "data": "0xbd549c840e3415871bfba8d089cfbf49b7529d3c767c211b623552e15a0e669c",
          "messageHash": "0x37f2afbcdd1a2313443ac28e29c63773ea1548143efaf390f204e5799053d373",
          "scheme": "eip191",
          "description": "Sign keccak256(abi.encode(identity, topic, data)) as an EIP-191 personal message with a wallet that holds a CLAIM key on 0xbacb9739Dd6D129B04d7Fc5B5c426c33429cC4E2",
          "claimType": "RESIDENCY"
        }
      ],
      "identities": {
        "0x96C5822784130360F904372b83E130be4A1894D6": "0x8986b6a837ccA6c6F6e257526296f07b9fe3fA9f"
      },
      "claimIssuer": "0xbacb9739Dd6D129B04d7Fc5B5c426c33429cC4E2",
      "claimTopic": "109015029463275868683647211611771110530627425002451180747115609001006883683411",
      "next": "Sign every messageHash as an EIP-191 personal message with a wallet that holds a CLAIM key on the trusted issuer, then repeat this call with claimSignatures: [{ walletAddress, signature }].",
      "total": 1,
      "ids": ["cmg1u7k3p0004l80h2f9s6d1x"],
      "rows": [
        { "id": "cmg1u7k3p0004l80h2f9s6d1x", "walletAddress": "0x96c5822784130360f904372b83e130be4a1894d6", "identity": "0x8986b6a837ccA6c6F6e257526296f07b9fe3fA9f" }
      ],
      "confirmWith": null
    },
    "error": null,
    "metadata": {
      "requestId": "550e8400-e29b-41d4-a716-446655440000",
      "timestamp": "2026-09-30T10:00:00.000Z"
    }
  }
  ```

  ```json ERC-3643 Register Phase theme={null}
  {
    "success": true,
    "data": {
      "register": "0xc9B421D7403A4eAfCC4ba5FE38E98691BAdBFa0E",
      "registerKind": "TREX",
      "signerAddress": "0xCD92134767aEC2562be15d2a2062A082dA17dD84",
      "claimSigners": ["0xCD92134767aEC2562be15d2a2062A082dA17dD84"],
      "action": "SIGN_TRANSACTIONS",
      "phase": "REGISTER",
      "steps": [
        {
          "action": "SIGN_TRANSACTION",
          "stepType": "claim",
          "walletAddress": "0x96C5822784130360F904372b83E130be4A1894D6",
          "identity": "0x8986b6a837ccA6c6F6e257526296f07b9fe3fA9f",
          "transaction": {
            "to": "0x8986b6a837ccA6c6F6e257526296f07b9fe3fA9f",
            "data": "0xb1a34e0d..."
          },
          "functionName": "addClaim",
          "description": "Add the KYC claim of 0x96C5822784130360F904372b83E130be4A1894D6 to its ONCHAINID 0x8986b6a837ccA6c6F6e257526296f07b9fe3fA9f",
          "claimType": "KYC",
          "dataHash": "0xd815320690e956adfd07197c275b560561fbf5aab2d633d3d46db748c468d0af",
          "id": "cmg1u7k3p0004l80h2f9s6d1x"
        },
        {
          "action": "SIGN_TRANSACTION",
          "stepType": "claim",
          "walletAddress": "0x96C5822784130360F904372b83E130be4A1894D6",
          "identity": "0x8986b6a837ccA6c6F6e257526296f07b9fe3fA9f",
          "transaction": {
            "to": "0x8986b6a837ccA6c6F6e257526296f07b9fe3fA9f",
            "data": "0xb1a34e0d..."
          },
          "functionName": "addClaim",
          "description": "Add the RESIDENCY claim of 0x96C5822784130360F904372b83E130be4A1894D6 to its ONCHAINID 0x8986b6a837ccA6c6F6e257526296f07b9fe3fA9f",
          "claimType": "RESIDENCY",
          "dataHash": "0xbd549c840e3415871bfba8d089cfbf49b7529d3c767c211b623552e15a0e669c",
          "id": "cmg1u7k3p0004l80h2f9s6d1x"
        },
        {
          "action": "SIGN_TRANSACTION",
          "stepType": "verify",
          "walletAddress": "0x96C5822784130360F904372b83E130be4A1894D6",
          "transaction": {
            "to": "0xc9B421D7403A4eAfCC4ba5FE38E98691BAdBFa0E",
            "data": "0x454a03e0..."
          },
          "functionName": "registerIdentity",
          "description": "Register 0x96C5822784130360F904372b83E130be4A1894D6 on the identity register 0xc9B421D7403A4eAfCC4ba5FE38E98691BAdBFa0E",
          "ids": ["cmg1u7k3p0004l80h2f9s6d1x"]
        }
      ],
      "confirmStepIndex": 2,
      "identities": {
        "0x96C5822784130360F904372b83E130be4A1894D6": "0x8986b6a837ccA6c6F6e257526296f07b9fe3fA9f"
      },
      "claimIssuer": "0xbacb9739Dd6D129B04d7Fc5B5c426c33429cC4E2",
      "claimTopic": "109015029463275868683647211611771110530627425002451180747115609001006883683411",
      "registerStep": "registerIdentity",
      "description": "Register 1 verified identity on the ERC-3643 identity register",
      "total": 1,
      "ids": ["cmg1u7k3p0004l80h2f9s6d1x"],
      "rows": [
        { "id": "cmg1u7k3p0004l80h2f9s6d1x", "walletAddress": "0x96c5822784130360f904372b83e130be4a1894d6", "identity": "0x8986b6a837ccA6c6F6e257526296f07b9fe3fA9f" }
      ],
      "confirmWith": {
        "endpoint": "POST /customers/api/identity/pending/confirm",
        "fields": [
          "ids",
          "txHash (the registerIdentity / batchRegisterIdentity transaction, omit when every wallet was already registered)",
          "claimTxResults: [{ id, txHash }] (one per claim step)"
        ]
      }
    },
    "error": null,
    "metadata": {
      "requestId": "550e8400-e29b-41d4-a716-446655440000",
      "timestamp": "2026-09-30T10:00:00.000Z"
    }
  }
  ```

  ```json Error - Country Blocked theme={null}
  {
    "success": false,
    "data": null,
    "error": {
      "code": "COUNTRY_BLOCKED",
      "message": "0xff21b8ac28bb6a20c1c0160af42303d2946b99ea: IRN is on the blocked-country list of the Retail verification profile (RETAIL), so a customer from IRN cannot be onboarded under it. Choose a verification profile that admits IRN, or change the profile's blocked countries under Customers › Verification Pro"
    },
    "metadata": {
      "requestId": "550e8400-e29b-41d4-a716-446655440000",
      "timestamp": "2026-09-30T10:00:00.000Z"
    }
  }
  ```
</ResponseExample>

## Error Codes

| Code | HTTP | Cause |
| - | - | - |
| `VALIDATION_ERROR` | `400` | `ids` is not an array of 1 to 200 ids |
| `INVALID_CLAIM_SIGNATURE` | `400` | A claim signature is not 65 bytes of hex, or recovers to no signer for its identity, topic and data |
| `COUNTRY_BLOCKED` | `403` | A row's country is on the blocked list of its verification profile. The whole call is refused |
| `KYC_PROVIDER_ROLE_MISSING` | `403` | Trusset register: none of your registered wallets holds `KYC_PROVIDER_ROLE` |
| `REGISTRY_AGENT_MISSING` | `403` | ERC-3643 register: none of your registered wallets is an agent of the register |
| `CLAIM_SIGNER_MISSING` | `403` | ERC-3643 register: neither `signerAddress` nor any of your registered wallets holds a CLAIM key on the register's trusted issuer |
| `CLAIM_SIGNER_NOT_TRUSTED` | `403` | `signerAddress`, or the wallet a claim signature recovers to, holds no CLAIM key on the trusted issuer |
| `NOT_FOUND` | `404` | None of the `ids` is a `PENDING` row of your instance, or the instance no longer exists |
| `OWN_REGISTRY_NOT_CONFIGURED` | `409` | Your instance is set to its own register but holds no valid register address |
| `REGISTRY_NO_CLAIM_TOPICS` | `409` | The ERC-3643 register requires no claim topic, so there is no claim to sign |
| `REGISTRY_NO_TRUSTED_ISSUER` | `409` | The register requires a claim topic but names no trusted issuer for it |
| `ONCHAINID_AUTHORITY_UNKNOWN` | `409` | A wallet needs an ONCHAINID, and no identity on the register shows which implementation authority to deploy it from |
| `REGISTRY_PROBE_FAILED` | `503` | The register or its trusted issuer could not be read. Retry shortly |
| `PENDING_CALLDATA_FAILED` | `400` | A chain read failed while building |
| `PENDING_CALLDATA_FAILED` | `500` | Any other failure |
