> For the complete documentation index, see [llms.txt](https://docs.selcier.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.selcier.xyz/build-on-selcier/rest-api.md).

# REST API

The complete Selcier HTTP interface, covering each endpoint's parameters, sample responses, list paging and error handling.

This page documents a REST interface served over HTTPS. Request bodies and responses are JSON, and outcomes are signaled with standard HTTP status codes. For authentication, environments, versioning and idempotency, go to [Keys and environments](/build-on-selcier/keys-and-environments.md).

| Environment | Base URL                             |
| ----------- | ------------------------------------ |
| Live        | `https://api.selcier.xyz/v1`         |
| Sandbox     | `https://api.sandbox.selcier.xyz/v1` |

## Shared formats

* **Naming.** Every field uses `snake_case`.
* **Amounts** travel as decimal strings in token units, `"1250.5"` for example. When precision matters, an object adds a `raw` field: a string holding the integer amount at 18 decimals. Stablecoins use this scheme too, each at its own decimals.
* **Addresses** appear as lowercase hex strings that begin with `0x`.
* **Times** are in UTC and formatted to ISO 8601, for example `"2026-11-04T16:00:00Z"`.
* **Transaction links.** When an object maps to a transaction, it carries `tx_hash`, `block_number` and `chain_id`.
* **Ids** are strings whose prefix shows the object type:

| Prefix | Object           |
| ------ | ---------------- |
| `cmp_` | Company          |
| `cls_` | Share class      |
| `hld_` | Holder           |
| `off_` | Offering         |
| `lqw_` | Liquidity Window |
| `dst_` | Distribution     |
| `prp_` | Proposal         |
| `doc_` | Document         |
| `val_` | Valuation        |
| `evt_` | Event            |
| `we_`  | Webhook endpoint |

## Paging through lists

Calling a list endpoint gets you one page of results, plus a flag showing whether anything remains.

```bash
curl "https://api.selcier.xyz/v1/holders?share_class=cls_3VbT9pLm&limit=50" \
  -H "Authorization: Bearer sk_live_..."
```

```json
{
  "object": "list",
  "data": [ { "id": "hld_A1b2C3d4", "object": "holder" } ],
  "has_more": true
}
```

| Parameter        | Effect                                                           |
| ---------------- | ---------------------------------------------------------------- |
| `limit`          | How many objects you want, between 1 and 100. The default is 50. |
| `starting_after` | Starts the page immediately after the object with this id.       |
| `ending_before`  | Finishes the page immediately before the object with this id.    |

Move forward by sending the id of the last object you got as `starting_after`. Auto-pagination in the [TypeScript client](/build-on-selcier/typescript-client.md) handles this for you.

## Error responses

Success shows up as a `2xx` status. Failure shows up as `4xx` or `5xx`, accompanied by one error object:

```json
{
  "error": {
    "type": "rule_violation",
    "code": "HOLDING_PERIOD_ACTIVE",
    "message": "The sender's tokens are still within the holding period set for this share class.",
    "request_id": "req_Qm7vX2pLk9"
  }
}
```

| `type`            | HTTP status   | What it tells you                                                                                                                |
| ----------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `invalid_request` | 400, 404, 409 | Absent or invalid parameter, or a conflict with current state                                                                    |
| `authentication`  | 401, 403      | Absent, invalid or revoked key, or a key without permission for this action                                                      |
| `rule_violation`  | 422           | Completing the action would break a transfer rule, and `code` carries the [outcome code](/build-on-selcier/transfer-outcomes.md) |
| `not_found`       | 404           | No such object exists, or the key has no view of it                                                                              |
| `rate_limited`    | 429           | The request rate is too high, so wait out the `Retry-After` interval before trying again                                         |
| `chain_error`     | 502, 503      | Submission to Robinhood Chain failed, or the transaction reverted there                                                          |

On an `invalid_request` error, `code` identifies the problem (`parameter_missing`, for instance) and a further `param` field identifies the parameter concerned.

## Company resources

Issuers onboarded to Selcier appear as company objects. Two identifiers apply. Off-chain, that is the `cmp_...` id. On-chain, it is the bytes32 `companyId`, exposed by the API as `company_id_onchain`.

| Method | Path                 | Purpose                                                             |
| ------ | -------------------- | ------------------------------------------------------------------- |
| `GET`  | `/v1/companies`      | Returns the companies visible to your key                           |
| `POST` | `/v1/companies`      | Sets up a company, with `SelcierFactory` deploying its contract set |
| `GET`  | `/v1/companies/{id}` | Returns one company by id                                           |

Main `POST` fields:

| Field             | Notes                                                              |
| ----------------- | ------------------------------------------------------------------ |
| `name`            |                                                                    |
| `legal_name`      |                                                                    |
| `country`         | ISO 3166 alpha-2                                                   |
| `issuer_multisig` | The company multi-sig address that is going to hold `ISSUER_ADMIN` |
| `registrar`       | The address that is going to hold `REGISTRAR`                      |
| `timelocks`       | Optional overrides, which must stay within the allowed bounds      |

```json
{
  "id": "cmp_8f2kQ1xZ",
  "object": "company",
  "name": "Larkway Robotics",
  "status": "deployed",
  "chain_id": 4663,
  "company_id_onchain": "0x6e6f7274...",
  "contracts": {
    "identity_registry": "0x...",
    "trusted_verifiers": "0x...",
    "offering_vault": "0x...",
    "liquidity_window": "0x...",
    "rfq_settlement": "0x...",
    "distribution_vault": "0x...",
    "governance": "0x...",
    "disclosure_registry": "0x...",
    "issuer_timelock": "0x..."
  },
  "share_classes": ["cls_3VbT9pLm"],
  "created_at": "2026-09-14T10:21:44Z"
}
```

## Share class resources

Behind every share class sits a single `SelcierShareToken`, and the class has a `RuleEngine` and `ValuationOracle` of its own.

| Method | Path                     | Purpose                                                                               |
| ------ | ------------------------ | ------------------------------------------------------------------------------------- |
| `GET`  | `/v1/share_classes`      | Returns share classes, optionally narrowed by `company`                               |
| `POST` | `/v1/share_classes`      | Adds a share class and triggers its deployment                                        |
| `GET`  | `/v1/share_classes/{id}` | Fetches a single share class, reporting module configuration, supply and holder count |

Main `POST` fields:

| Field         | Notes                                                                                                                                                        |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `company`     |                                                                                                                                                              |
| `name`        |                                                                                                                                                              |
| `symbol`      |                                                                                                                                                              |
| `modules`     | Object keyed by module name, using `region`, `eligibility`, `holding_period`, `holder_cap`, `transfer_window`, `rofr`, `max_ownership` or `employee_vesting` |
| `rfq_enabled` | Boolean, `false` unless set                                                                                                                                  |

When you retrieve one, you also get `token_address`, `rule_engine_address`, `valuation_oracle_address`, `total_supply`, `holder_count`, `ui_multiplier` (a decimal string, by default `"1.0"`), `paused`, and `status` (`deploying`, `deployed` or `failed`).

## Holder resources

| Method | Path                    | Purpose                                                                                                     |
| ------ | ----------------------- | ----------------------------------------------------------------------------------------------------------- |
| `GET`  | `/v1/holders`           | Returns holders, optionally narrowed by `company`, `share_class` and `status`                               |
| `POST` | `/v1/holders`           | Sends a holder an email invitation, after which wallet setup and identity verification fall to Selcier      |
| `GET`  | `/v1/holders/{id}`      | Looks up a single holder and includes their balances, claims and wallets                                    |
| `GET`  | `/v1/holders/{id}/lots` | Returns a holder's lots, showing when each was acquired, when its holding period ends and its vesting state |

Main `POST` fields:

| Field         | Notes                                                                                             |
| ------------- | ------------------------------------------------------------------------------------------------- |
| `company`     |                                                                                                   |
| `email`       |                                                                                                   |
| `name`        |                                                                                                   |
| `wallet`      | Optional existing address                                                                         |
| `claims`      | Optional, such as `{ "employee_of": true }`                                                       |
| `allocations` | Optional. Entries shaped `{ share_class, amount, reference }`, minted once the holder is verified |

`wallets`, `claims` and `status` all appear on a holder object. The status is one of `invited`, `verifying`, `verified` or `restricted`. Each entry in the claims array has the shape `{ topic, value, verifier, expires_at }`. Nothing personal in these responses gets written on-chain, and it stays within Selcier's access-controlled systems.

## Pre-flight transfer checks

| Method | Path                  | Purpose                                              |
| ------ | --------------------- | ---------------------------------------------------- |
| `POST` | `/v1/transfers/check` | Tests a transfer against all rules and sends nothing |

Publishable keys may call this endpoint. Send four parameters, namely `share_class`, `from`, `to` and `amount`.

```json
{
  "object": "transfer_check",
  "ok": false,
  "reason_code": "WINDOW_CLOSED",
  "message": "Transfers in this share class are only allowed during an open Liquidity Window.",
  "evaluated_at_block": 18204417
}
```

The answer reflects what `canTransfer` on the token would return at `evaluated_at_block`.

## Offering resources

| Method | Path                       | Purpose                                                                                                                                                                               |
| ------ | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET`  | `/v1/offerings`            | Retrieves offerings as a paged list, with optional `company`, `share_class` and `status` filters                                                                                      |
| `POST` | `/v1/offerings`            | Writes the terms of a raise to the `OfferingVault` contract as an offering                                                                                                            |
| `POST` | `/v1/offerings/{id}/close` | Settles the offering, minting shares or marking it failed. It can run from `closes_at` onward, and the company can also close early once `max_raise` (`maxRaise` on-chain) is reached |

Main fields for `POST /v1/offerings`:

| Field             | Notes                                                |
| ----------------- | ---------------------------------------------------- |
| `share_class`     |                                                      |
| `price_per_share` |                                                      |
| `min_raise`       |                                                      |
| `max_raise`       |                                                      |
| `min_ticket`      |                                                      |
| `opens_at`        |                                                      |
| `closes_at`       |                                                      |
| `stablecoin`      | `usdg` if omitted                                    |
| `eligible_claims` | Array of claim topics                                |
| `documents`       | Array of `doc_` ids anchored in `DisclosureRegistry` |

An offering object reports `status` (`scheduled`, `open`, `closed` or `failed`), `raised` and `subscriber_count`. Closed offerings add `shares_issued` and `close_tx_hash`. More background is in [Raising primary capital](/markets-and-capital/primary-raises.md).

## Liquidity Window resources

| Method | Path                                | Purpose                                                                             |
| ------ | ----------------------------------- | ----------------------------------------------------------------------------------- |
| `GET`  | `/v1/liquidity_windows`             | Retrieves Liquidity Windows as a paged list                                         |
| `POST` | `/v1/liquidity_windows`             | Puts a window on the schedule                                                       |
| `POST` | `/v1/liquidity_windows/{id}/cancel` | Calls off a window ahead of clearing, which frees any locked tokens and stablecoins |
| `GET`  | `/v1/liquidity_windows/{id}/orders` | Shows which orders have gone into a given window                                    |

Main `POST` fields:

| Field                           | Notes                             |
| ------------------------------- | --------------------------------- |
| `share_class`                   |                                   |
| `mode`                          | `auction` or `tender`             |
| `opens_at`                      |                                   |
| `closes_at`                     |                                   |
| `seller_claims`, `buyer_claims` | Filters by claim topic            |
| `reserve_price`                 | Optional                          |
| `max_volume`                    | Optional                          |
| `per_seller_cap`                | Optional                          |
| `rofr_holder`, `rofr_period`    | Optional                          |
| `tender_price`                  | Mandatory when `mode` is `tender` |

`clearing_price`, `volume` and `clear_tx_hash` become available when a window has cleared. For the mechanics, read [Scheduled Liquidity Windows](/markets-and-capital/scheduled-windows.md).

## Distribution resources

| Method | Path                | Purpose                                                                  |
| ------ | ------------------- | ------------------------------------------------------------------------ |
| `GET`  | `/v1/distributions` | Retrieves distributions as a paged list                                  |
| `POST` | `/v1/distributions` | Moves the payout funds into `DistributionVault`, creating a distribution |

Main fields:

| Field                         | Notes                                                             |
| ----------------------------- | ----------------------------------------------------------------- |
| `share_class`                 |                                                                   |
| `asset`                       | `usdg` if omitted                                                 |
| `amount`                      |                                                                   |
| `record_block` or `record_at` | `record_at` is a time, resolved to the first block at or after it |
| `claim_deadline`              | Optional, no sooner than 12 months after funding                  |
| `reference`                   |                                                                   |

## Proposal resources

| Method | Path            | Purpose                                          |
| ------ | --------------- | ------------------------------------------------ |
| `GET`  | `/v1/proposals` | Returns proposals, with the results for each     |
| `POST` | `/v1/proposals` | Opens a vote in `Governance`, weighted by tokens |

Main fields:

| Field            | Notes                        |
| ---------------- | ---------------------------- |
| `share_classes`  |                              |
| `title`          |                              |
| `options`        |                              |
| `snapshot_block` | The current block if omitted |
| `ends_at`        |                              |
| `quorum`         |                              |
| `binding`        | Boolean                      |
| `documents`      |                              |

## Document resources

| Method | Path            | Purpose                                                                                  |
| ------ | --------------- | ---------------------------------------------------------------------------------------- |
| `GET`  | `/v1/documents` | Returns the documents that have been anchored                                            |
| `POST` | `/v1/documents` | Accepts an uploaded document, whose hash then gets anchored through `DisclosureRegistry` |

Main fields:

| Field        | Notes                                                                                                                              |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| `company`    |                                                                                                                                    |
| `kind`       | One of `SHARE_CLASS_TERMS`, `OFFERING_DOCUMENT`, `FINANCIAL_STATEMENT`, `COMPANY_UPDATE`, `BOARD_RESOLUTION` or `VALUATION_REPORT` |
| `file`       | Sent as a multipart upload                                                                                                         |
| `visibility` | `holders` or `public`                                                                                                              |

In the response you will find the anchored SHA-256 `hash` together with the on-chain `document_id`.

## Valuation resources

| Method | Path             | Purpose                                                                             |
| ------ | ---------------- | ----------------------------------------------------------------------------------- |
| `GET`  | `/v1/valuations` | Returns the Reference Valuations of one share class, readable with publishable keys |
| `POST` | `/v1/valuations` | Uses `ValuationOracle` to publish a Reference Valuation                             |

Main `POST` fields:

| Field         | Notes                                     |
| ------------- | ----------------------------------------- |
| `share_class` |                                           |
| `price`       | USD per share                             |
| `source`      | `PRICED_ROUND` or `INDEPENDENT_VALUATION` |
| `as_of`       |                                           |
| `document`    | A `doc_` id                               |

Clearing a Liquidity Window publishes a valuation automatically, with `WINDOW_CLEARING` as its source. [How a valuation gets on-chain](/fundamentals/valuation-publishing.md) explains the process.

## Indexed events

| Method | Path         | Purpose                                        |
| ------ | ------------ | ---------------------------------------------- |
| `GET`  | `/v1/events` | Returns on-chain events that have been indexed |

You can filter on `company`, `share_class`, `type` (a [chain event](/build-on-selcier/chain-events.md) name, `SharesIssued` for instance), `from_block` and `to_block`. Returned events expose `tx_hash`, `block_number`, `log_index`, `contract`, `args`, and a `confirmation` value of `sequencer` or `l1`.

## Contract addresses

| Method | Path            | Purpose                                                                                            |
| ------ | --------------- | -------------------------------------------------------------------------------------------------- |
| `GET`  | `/v1/contracts` | Returns the addresses of contracts deployed on the current network, readable with publishable keys |

A bare call yields the `SelcierFactory` address plus the module implementations. Passing `company` yields that company's full contract set. For addresses, rely on this endpoint or the Explorer, since those two are authoritative. The [Smart contract map](/build-on-selcier/smart-contracts.md) describes each contract.

## Webhook endpoint resources

| Method   | Path                         | Purpose                                                                    |
| -------- | ---------------------------- | -------------------------------------------------------------------------- |
| `GET`    | `/v1/webhook_endpoints`      | Retrieves registered endpoints as a paged list                             |
| `POST`   | `/v1/webhook_endpoints`      | Adds an endpoint and returns its signing `secret`, which appears only once |
| `DELETE` | `/v1/webhook_endpoints/{id}` | Removes the endpoint with this id                                          |

Send `url` and `description` in a `POST`, along with `events`. That last field holds event types as an array, or `["*"]` for all of them. Continue with [Event delivery](/build-on-selcier/event-delivery.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.selcier.xyz/build-on-selcier/rest-api.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
