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

# Set Whitelist Members

> Build the transactions that list or remove wallets on a whitelist

Builds the `setListed` transactions that list wallets on a whitelist, or remove them. The list's owner or any of its managers signs. Up to 2,000 wallets are accepted in one request and split into transactions of at most 200, each signed and confirmed on its own with [Confirm Whitelist Members](/endpoints/lending/confirm-access-list-members).

This works on a list your instance keeps and on a list another instance keeps that one of your verified wallets manages. On the second, the response carries `managed: true`, and only your managing wallet can sign.

<Warning>
  A removal takes effect only once its transaction is mined. Until then the wallet stays listed and keeps passing every gate the list serves. When the list gates markets, the build names in `warnings` the open loans whose borrower or fixed payee is being removed. A removed borrower can still repay, add collateral and close its loan, but cannot draw more on it. A removed payee blocks every further draw on the loan it is paid for, because a loan's payee cannot be changed.
</Warning>

## Who signs

The signer must be the list's owner or one of its managers on chain, or the list refuses the change. Name it in `signerAddress`. Omitted, the first verified wallet of your instance that is the owner or a manager is used, and failing that the first verified wallet. A wallet that is neither is refused with `NOT_ACCESS_LIST_MANAGER`, and `details` names the signer and the owner. On a list another instance keeps, `signerAddress` must also be a verified wallet of your instance.

The first transaction is simulated before anything is returned, so a change the list would refuse answers with the refusal instead of calldata.

## Path Parameters

<ParamField path="listId" type="string" required>
  The whitelist ID from [List Whitelists](/endpoints/lending/list-access-lists).
</ParamField>

## Body Parameters

<ParamField body="accounts" type="string[]" required>
  The wallets to list or remove: 1 to 2,000 addresses. Duplicates are dropped.
</ParamField>

<ParamField body="listed" type="boolean" required>
  `true` lists the wallets, `false` removes them.
</ParamField>

<ParamField body="signerAddress" type="string">
  The owner or manager that will sign.
</ParamField>

## Response Fields

One batch answers `SIGN_TRANSACTION` with `transaction`. More than 200 wallets answer `SIGN_TRANSACTIONS` with `steps`, one per batch of 200, each to be confirmed after it mines.

<ResponseField name="data" type="object">
  <Expandable>
    <ResponseField name="action" type="string">`SIGN_TRANSACTION` or `SIGN_TRANSACTIONS`.</ResponseField>
    <ResponseField name="transaction" type="object">The `setListed` call on the list, `{ to, data, chainId, value }`, for a single batch.</ResponseField>
    <ResponseField name="functionName" type="string">`setListed`, for a single batch.</ResponseField>
    <ResponseField name="description" type="string">What the batch lists or removes, for a single batch.</ResponseField>
    <ResponseField name="steps" type="array">For several batches: each with `action`, `transaction`, `functionName`, `description`, `authority` (`ACCESS_LIST_MANAGER`), `accounts` (the batch) and `confirmWith`.</ResponseField>
    <ResponseField name="confirmEach" type="boolean">`true` with `steps`: confirm every step's hash.</ResponseField>
    <ResponseField name="listId" type="string">The whitelist ID.</ResponseField>
    <ResponseField name="listAddress" type="string">The list contract, checksummed.</ResponseField>
    <ResponseField name="listed" type="boolean">Echoes the request.</ResponseField>
    <ResponseField name="accounts" type="integer">How many distinct wallets the request names.</ResponseField>
    <ResponseField name="signer" type="string">The wallet that must sign, checksummed.</ResponseField>
    <ResponseField name="signerRole" type="string">`OWNER` or `MANAGER`.</ResponseField>
    <ResponseField name="maxBatch" type="integer">`200`.</ResponseField>
    <ResponseField name="warnings" type="array">`{ code, message }` entries. See [Warnings](#warnings).</ResponseField>
    <ResponseField name="confirmWith" type="object">`{ endpoint, txHash, field, path }`, with `path` naming [Confirm Whitelist Members](/endpoints/lending/confirm-access-list-members) for this list.</ResponseField>
    <ResponseField name="managed" type="boolean">Present and `true` on a list another instance keeps.</ResponseField>
    <ResponseField name="managedBy" type="string">Your wallet that manages it. Present with `managed`.</ResponseField>
  </Expandable>
</ResponseField>

## Warnings

| `code` | When |
| - | - |
| `REMOVAL_TAKES_EFFECT_WHEN_SIGNED` | On every removal. The wallets stay listed until the transaction mines |
| `AFFECTS_OPEN_LOANS` | On a removal, when a wallet being removed borrows on, or is the fixed payee of, an open loan of a market whose recorded borrower gate is this list. Carries `loans`, each `{ marketAddress, loanId, role, wallet }` with `role` `BORROWER` or `PAYEE` |
| `LIST_SCOPE` | When the list serves a gate of your instance or of the instance that keeps it. Names those markets, vaults and vault groups. The change applies to all of them at once, and to any product of another instance that installed the list |

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/access-lists/cmv2k8q1d0004l70a3n6p2w9e/members" \
    -H "X-API-Key: trusset_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{"accounts": ["0x6a6cba16dad34f7ea7ecbcdbf050f8146b942d6b"], "listed": false}'
  ```

  ```typescript TypeScript theme={null}
  const url = `https://api.trusset.org/lending-external-securities-v2/api/access-lists/${listId}`;
  const headers = { 'X-API-Key': 'trusset_your_key_here', 'Content-Type': 'application/json' };

  const res = await fetch(`${url}/members`, {
    method: 'POST',
    headers,
    body: JSON.stringify({ accounts: wallets, listed: true })
  });
  const { data } = await res.json();
  const batches = data.action === 'SIGN_TRANSACTIONS' ? data.steps : [data];

  for (const batch of batches) {
    const tx = await managerWallet.sendTransaction(batch.transaction);
    await tx.wait();
    await fetch(`${url}/members/confirm`, { method: 'POST', headers, body: JSON.stringify({ txHash: tx.hash }) });
  }
  ```
</RequestExample>

<ResponseExample>
  ```json Response - Removal theme={null}
  {
    "success": true,
    "data": {
      "action": "SIGN_TRANSACTION",
      "transaction": {
        "to": "0x7D31E6b09A4c25F8e1B73d0a6C94e2F58b1A0C37",
        "data": "0x...",
        "chainId": 11155111,
        "value": "0"
      },
      "functionName": "setListed",
      "description": "Remove 1 wallet from the whitelist (transaction 1 of 1)",
      "listId": "cmv2k8q1d0004l70a3n6p2w9e",
      "listAddress": "0x7D31E6b09A4c25F8e1B73d0a6C94e2F58b1A0C37",
      "listed": false,
      "accounts": 1,
      "signer": "0x1234F9a07C6b53D81e2A4f70C9B385D6014a7E52",
      "signerRole": "OWNER",
      "maxBatch": 200,
      "warnings": [
        {
          "code": "REMOVAL_TAKES_EFFECT_WHEN_SIGNED",
          "message": "A removal takes effect on chain only once its transaction is signed and mined; until then the wallet stays listed and keeps passing the gate."
        },
        {
          "code": "AFFECTS_OPEN_LOANS",
          "message": "The wallets being removed take part in an open loan of markets this whitelist gates: loan 12 of market 0x5B1F0c8E2a7D93E46B1c8F2A9d04E7A3c6B15F21 (0x6A6cBa16DAD34F7ea7eCbCdbF050f8146B942D6b borrows on it). A removed borrower can still repay, add collateral and close its loan, but cannot borrow more on it.",
          "loans": [
            {
              "marketAddress": "0x5B1F0c8E2a7D93E46B1c8F2A9d04E7A3c6B15F21",
              "loanId": "12",
              "role": "BORROWER",
              "wallet": "0x6A6cBa16DAD34F7ea7eCbCdbF050f8146B942D6b"
            }
          ]
        },
        {
          "code": "LIST_SCOPE",
          "message": "This change applies at once to every gate this whitelist serves, here: the borrower gate of market 0x5B1F0c8E2a7D93E46B1c8F2A9d04E7A3c6B15F21. A product of another instance that installed this whitelist follows its members too."
        }
      ],
      "confirmWith": {
        "endpoint": "members/confirm",
        "txHash": true,
        "field": "txHash",
        "path": "POST /lending-external-securities-v2/api/access-lists/cmv2k8q1d0004l70a3n6p2w9e/members/confirm"
      }
    }
  }
  ```

  ```json Error - Not a Manager theme={null}
  {
    "success": false,
    "error": {
      "code": "NOT_ACCESS_LIST_MANAGER",
      "message": "0x9C1e57A2D0B34f86E7a15C9D2b4F60e38A7D4b70 is neither the owner nor a manager of this whitelist, so the list would refuse the change. The owner adds managers.",
      "details": {
        "signer": "0x9c1e57a2d0b34f86e7a15c9d2b4f60e38a7d4b70",
        "owner": "0x1234f9a07c6b53d81e2a4f70c9b385d6014a7e52"
      }
    }
  }
  ```
</ResponseExample>

## Error Codes

| Code | HTTP | Cause |
| - | - | - |
| `VALIDATION_ERROR` | `400` | `accounts` is empty, holds more than 2,000 entries or a malformed address, `listed` is not a boolean, or `signerAddress` is malformed |
| `INVALID_ADDRESS` | `400` | A wallet or `signerAddress` is the zero address or fails its EIP-55 checksum |
| `NOT_ACCESS_LIST_MANAGER` | `403` | The signer is neither the owner nor a manager of the list on chain, or, on a list another instance keeps, `signerAddress` is not a verified wallet of your instance |
| `ACCESS_LIST_NOT_FOUND` | `404` | No whitelist with this ID is kept by your instance, or managed or pending to one of its wallets, on this network |
| `TX_WOULD_REVERT` | `409` | The first batch would revert for another reason. `details.revert` names the contract error where known |
| `WALLET_NOT_CONFIGURED` | `412` | Your instance has no verified wallet to sign |
| `ACCESS_LIST_MEMBERS_FAILED` | `500` | The change could not be prepared and no more specific code applied |
| `ACCESS_LISTS_NOT_CONFIGURED` | `503` | The whitelist factory is not deployed on this network |
| `ACCESS_LIST_UNREADABLE` | `503` | The list's owner and managers could not be read, so the signer could not be checked. Retry shortly |
| `CHAIN_UNAVAILABLE` | `503` | The chain could not be read to simulate the change. Retry shortly |
| `SERVICE_UNAVAILABLE` | `503` | Your instance's verified wallets could not be read. Retry shortly |


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