# Contract inspector API reference

Source: https://docs.settlemint.com/docs/api-reference/reference/contract-inspector
Inspect any on-chain address through the DALP Platform API to read its token metadata, detect a SMART (ERC-3643) interface, see how the active organization already knows it, and check external-token registration eligibility.



The contract inspector answers one question before you act on an address: what is deployed here, and can I register it? Send one address and read back a deliberately small preview. The response reports whether the address has code, a best-effort token snapshot, whether it advertises a SMART (ERC-3643 family) interface, how the active organization already classifies it, and a registration eligibility verdict. The Console external-token register sheet uses this endpoint to render its preview card and gate the submit button. You can call it directly to build the same preflight in your own integration.

This surface is read-only. It reads on-chain state and indexed knowledge. It does not create, change, register, or delete anything.

## Endpoint [#endpoint]

| Endpoint                          | Use it for                                                                                               | Returns                                                |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
| `GET /api/v2/contracts/{address}` | Preview any address before registering an external token, reconciling a holding, or routing an operator. | Single-resource envelope with `data` and `links.self`. |

The call runs in the active organization's system: it combines that organization's indexed knowledge with live chain reads on the network the system runs on. The path parameter accepts a contract address in any case; the response echoes it as an EIP-55 checksummed address.

## Request [#request]

```bash
curl "https://your-platform.example.com/api/v2/contracts/0x71C7656EC7ab88b098defB751B7401B5f6d8976F" \
  -H "X-Api-Key: <api-key>"
```

You need an active organization for the call. API-key calls run in the organization the key belongs to. See [request headers](/docs/api-reference/reference/request-headers) for the participant, wallet, and organization headers the Platform API reads.

## Response [#response]

```json
{
  "data": {
    "address": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
    "hasCode": true,
    "token": {
      "name": "External Wrapped Bitcoin",
      "symbol": "XWBTC",
      "decimals": 18,
      "totalSupply": "21000000.0"
    },
    "isSmart": false,
    "knownTo": null,
    "registration": {
      "eligible": true,
      "blockingReason": null
    }
  },
  "links": {
    "self": "/v2/contracts/0x71C7656EC7ab88b098defB751B7401B5f6d8976F"
  }
}
```

### Response fields [#response-fields]

| Field                         | Type                     | Meaning                                                                                                                         |
| ----------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| `address`                     | string                   | The inspected address, EIP-55 checksummed.                                                                                      |
| `hasCode`                     | boolean                  | Whether the address has deployed bytecode on the active chain. A plain wallet address returns `false`.                          |
| `token`                       | object or `null`         | Best-effort ERC-20 preview. `null` when the address has no code or no ERC-20 method responded.                                  |
| `token.name`                  | string or `null`         | ERC-20 `name()` if it responded.                                                                                                |
| `token.symbol`                | string or `null`         | ERC-20 `symbol()` if it responded.                                                                                              |
| `token.decimals`              | integer or `null`        | ERC-20 `decimals()` if it responded and is in range; otherwise `null`.                                                          |
| `token.totalSupply`           | decimal string or `null` | ERC-20 `totalSupply()` formatted with `decimals`. `null` when either probe failed, so the value is never silently misformatted. |
| `isSmart`                     | boolean                  | Whether the contract reports a non-empty `registeredInterfaces()` array. The variant and interface IDs are not exposed here.    |
| `knownTo`                     | enum or `null`           | How the active organization already classifies the address. See [Classification](#classification).                              |
| `registration.eligible`       | boolean                  | Whether the address can be registered as an external token in the active organization right now.                                |
| `registration.blockingReason` | enum or `null`           | Why registration would fail, or `null` when eligible. See [Registration eligibility](#registration-eligibility).                |

Each token sub-field is independently nullable, so a partially compliant contract that exposes `name` and `symbol` but no `decimals` still produces a useful preview.

## Classification [#classification]

`knownTo` reports how the active organization already knows the address. It does not describe the contract in general terms; it answers "have we seen this here before?"

| `knownTo`        | Meaning                                                                                              |
| ---------------- | ---------------------------------------------------------------------------------------------------- |
| `factory-token`  | A token this organization deployed through its token factory.                                        |
| `external-token` | A token already registered in this organization's external token registry.                           |
| `system`         | Part of this organization's system contracts, such as a registry, a factory, or a compliance module. |
| `null`           | The address is not known to this organization. The contract may still hold a valid token on-chain.   |

The `system` value is intentionally not sub-classified. The only signal a caller needs is that the address belongs to the system and must not be registered as an external token.

## Registration eligibility [#registration-eligibility]

The `registration` block is a preflight verdict for [external-token registration](/docs/api-reference/external-tokens/external-tokens). Register a token only when `eligible` is `true`. Any other state means the inspector considers the address ineligible, and `blockingReason` names why. The registration mutation performs its own checks, so the inspector verdict and the server-side result can differ for some edge cases.

| `blockingReason`     | Why registration is blocked                                                                |
| -------------------- | ------------------------------------------------------------------------------------------ |
| `no-code`            | The address has no deployed bytecode on the active chain, so there is nothing to register. |
| `already-registered` | The address is already an external token in this organization's registry.                  |
| `system-managed`     | The address is a factory-deployed token or a system contract, which the platform owns.     |
| `null`               | No blocking reason. `registration.eligible` is `true`.                                     |

When more than one condition applies, the response reports the most specific blocking reason: a missing contract reports `no-code` before any classification, and an already-registered token reports `already-registered` before `system-managed`.

<Callout type="info" title="Use the verdict, but expect one more check at registration">
  Gate registration on `registration.eligible` to avoid blocked submissions. A `true` verdict means the address has code and is not already registered or system-managed. The registration mutation then verifies that the contract exposes readable ERC-20 `symbol()` and `decimals()`; if either call fails, the mutation rejects the address with `EXTERNAL_TOKEN_NOT_ERC20`.
</Callout>

## Behavior to expect [#behavior-to-expect]

* A wallet address or an address with no contract returns `hasCode: false`, `token: null`, `isSmart: false`, and `registration.blockingReason: "no-code"`.
* A standards-compliant ERC-20 contract that this organization has never seen returns a populated `token`, `knownTo: null`, and `registration.eligible: true`.
* A SMART (ERC-3643 family) token returns `isSmart: true`. Tokens this organization issued through its factory also return `knownTo: "factory-token"` and a `system-managed` blocking reason, because the platform already manages them.
* `totalSupply` is `null` whenever `decimals` is `null`. The platform does not assume 18 decimals, which would misformat a 6-decimal stablecoin.

## Related references [#related-references]

* [External tokens](/docs/api-reference/external-tokens/external-tokens) registers an inspected address and lists tokens already recorded as external.
* [Asset decimals](/docs/api-reference/reference/asset-decimals) explains how the platform formats and serializes token amounts.
* [Request headers](/docs/api-reference/reference/request-headers) lists the organization, participant, and wallet headers the Platform API reads.
* [API reference](/docs/api-reference/reference/openapi) lists the available endpoints.
