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

# Get corporate actions for a market

> Returns one market's splits, reverse splits, stock dividends and cash dividends that are upcoming or took effect in the last 60 days, each in its latest status (an empty list when it has none).


> [!NOTE]
>
> **The response body shown here is a static example, not live data.** After you click **Send**, your live result appears in a separate panel headed **200 OK**. The panel under the status-code tabs is a fixed sample from the spec — its field values (fees, prices, sizes, IDs, timestamps) are placeholders. Use **Send**, or call the endpoint, for current values.

Returns one market's splits, reverse splits, stock dividends and cash dividends that are upcoming or took effect in the last 60 days, each in its latest status (an empty list when it has none).


## OpenAPI

````yaml /api-reference/openapi.yml get /v1/corporateActions/{market_id}
openapi: 3.1.0
info:
  title: Arcus API
  version: openapi-2026.11.12
  description: >
    REST API for the Arcus exchange. Provides endpoints for order management,
    market data, and account onboarding.


    ## Authentication

    Order management and credential-creating endpoints require **three** request
    headers:


    - `X-API-Key` — hex-encoded Ed25519 public key (64 chars). The public key
    *is* the API key. Obtain/register one via `POST /createApiKey`.

    - `X-Timestamp` — Unix time in **nanoseconds** as a decimal string (e.g.
    `"1713825891591000000"`). Millisecond or second epochs are rejected with
    `401 Unauthorized`. Must be within ±30,000 ms of server wall-clock;
    otherwise the request is rejected with `401 Unauthorized`.

    - `X-Signature` — lowercase hex-encoded Ed25519 signature (128 chars).


    **Single-order endpoints** (`placeOrder`, `cancelOrder`, `modifyOrder`) use
    the **ordersign typed canonical payload** as the signing message — a
    compact, key-sorted JSON object with engine-native integer values. The
    payload is NOT the raw HTTP body; it is built from the parsed request
    fields:

      ```
      placeOrder:   {"ad":"0x…","ai":N,[,"c":"…"],"ct":N,"g":N,"m":N,"op":1,"p":N,"q":N,"r":0|1,"s":N,"t":N,"v":1}
      cancelOrder:  {"ad":"0x…","ai":N,[,"c":"…"],"ct":N,[,"id":"…"],"m":N,"op":2,"v":1}
      modifyOrder:  {"ad":"0x…","ai":N,[,"c":"…"],"ct":N,"g":N,[,"id":"…"],"m":N,"op":3,"p":N,"q":N,"r":0|1,"s":N,"t":N,"v":1}   (exactly one of id / c)
      ```

    `ct` in the payload must equal `X-Timestamp`. Integer values `p`, `q` etc.
    are engine-native ticks/quantums, not human-readable decimals. Keys in
    brackets are conditional (omitted when empty). `op` is the operation enum:
    `1`=place, `2`=cancel, `3`=modify, `4`=placeUntriggered (TPSL). See the
    signing reference below for the full field definitions and reference signing
    code.


    **Batch endpoints still require this header to be present** (its value is
    not verified) — see below.

    - **Batch endpoints are signed per order, but the `X-Signature` header must
    still be present.** `POST /batchPlaceOrders`, `POST /batchCancelOrders`, and
    `POST /batchModifyOrders` require `X-API-Key` + `X-Timestamp` +
    `X-Signature`; the gateway does **not** verify the envelope `X-Signature`
    *value* for these routes (set it to any one element's signature), but
    omitting it — or sending an empty value — rejects every element with
    `invalid order signature`. Instead, each element of the `orders` / `cancels`
    / `modifies` array embeds its own `"signature"` field — a 128-hex Ed25519
    signature over the **ordersign typed canonical payload** for that operation:

        - Plain `orders` elements (no `tpsl_type`) use `op=1`.
        - TPSL / conditional `orders` elements (with `tpsl_type`) use `op=4`
          (`OpPlaceUntriggered`) — same field set as `op=1` but a different `op` value,
          preventing replay of a TPSL signature as a plain placeOrder.
        - `cancels` elements use `op=2`.
        - `modifies` elements use `op=3` — the same payload as a standalone `modifyOrder`.

    The `ct` field inside every element's payload must equal the shared
    `X-Timestamp` header value. The whole batch consumes a single replay slot.


    Read-only endpoints (`GET /openOrders`, `GET /fills`, etc.) require only
    `X-API-Key`. In relaxed local development the gateway may run with
    signatures disabled; the OpenAPI `security` blocks list `signedRequest` (the
    three-header AND) or `{}` (empty) to reflect that.


    ## Account-scoped requests

    Public account info reads such as fills, positions, orders, open orders, and
    account snapshots require `address` as a **query parameter**. Signed order
    management requests also require `address`, and it must match the master
    Ethereum address returned for that API key from `POST /createApiKey`.
    WebSocket `placeOrder` / `cancel` / `batchPlaceOrders` / `batchCancelOrders`
    / `modifyOrder` / `batchModifyOrders` use the same value in the JSON payload
    field `address`.


    ## Order execution is asynchronous

    `POST /placeOrder`, `POST /cancelOrder`, `POST /batchPlaceOrders`, `POST
    /batchCancelOrders`, and `POST /batchModifyOrders` are asynchronous. They
    return either:


    - **`202 Accepted`** — the common case. The signed request was validated by
    the gateway and forwarded to the matching engine; the body does **not**
    carry the order's terminal state.

    - **`200 OK`** — returned only when the gateway already has definitive state
    for the request by the time it responds (the body's `status` reflects that
    state, e.g. `OPEN` / `FILLED` / `CANCELED` / `REJECTED`). Clients should
    treat this as best-effort enrichment and not rely on it.


    In both cases the body echoes `orderId` / `clientId` so callers can
    correlate WebSocket events with the request. To observe the full order
    lifecycle (`OPEN`, `FILLED`, `CANCELED`, `REJECTED`, fills, rejection
    reasons, etc.) clients **must** subscribe to the `orders` WebSocket channel
    (and `userFills` for trade-level events). Treat both the `202` and `200`
    HTTP bodies as request acknowledgements; all definitive state lives on the
    WebSocket.


    ## Order rejection reasons

    When the matching engine rejects an order, the resulting `AccountUpdate`
    event (delivered over the WebSocket `account` channel with `type: REJECTED`)
    carries a `rejectionReason` enum. The same value may also appear on HTTP
    `OrderResponse` / `CancelOrderResponse` bodies that resolved to definitive
    state before returning (the `200` path described above). The complete set of
    reasons the matching engine can emit today is:


    | Value                        |
    Meaning                                                                 |

    |------------------------------|-------------------------------------------------------------------------|

    | `POST_ONLY_WOULD_CROSS`      | Post-only order was rejected because it
    would have crossed the book and taken liquidity. |

    | `SELF_TRADE`                 | Order would have matched against another
    resting order belonging to the same account; self-trade prevention rejected
    it. |

    | `UNDERCOLLATERALIZED`        | Account has insufficient free collateral /
    margin to support the order. |

    | `COULD_NOT_FILL`             | Generic "could not fill" outcome. Legacy
    reason — prefer the IOC/FOK-specific values below for time-in-force-driven
    cancels. |

    | `IOC_CANCELED`               | An `IMMEDIATE_OR_CANCEL` order produced
    zero fills against the book and was canceled. |

    | `FOK_FAILED`                 | A `FILL_OR_KILL` order could not be filled
    in full at submission and was canceled in its entirety. |

    | `REDUCE_ONLY_WOULD_INCREASE` | A `reduceOnly` order was rejected because
    executing it would have opened or increased the account's position rather
    than reducing it. |

    | `TOO_MANY_CLIENT_IDS`        | Account already has 10,000 live `clientId`s
    (the per-account maximum). Cancel an existing order or wait for one to reach
    a terminal state to free a slot. |

    | `DUPLICATE_CLIENT_ID`        | The `clientId` already maps to a live order
    on this account. Cancel the prior order (or change it with `modifyOrder`)
    before reusing the same `clientId`. |


    See the `RejectionReason` schema for the canonical enum.


    ## Rate limiting

    Rate-limited endpoints return `429 Too Many Requests` carrying two
    retry-after signals:


    - `Retry-After` HTTP header (integer seconds, RFC 7231 compliant).

    - `retryAfterMs` field in the JSON body — precise milliseconds.


    The body also carries a typed `reason` indicating which layer rejected
    (`ip`, `account_empty`, `account_partial`). See `RateLimitedError` for the
    schema and `TooManyRequests` for the behavioral contract.
servers:
  - url: https://api.arcus.xyz
    description: Mainnet
  - url: https://api.testnet.arcus.xyz
    description: Testnet
security: []
tags:
  - name: Onboarding
    description: Account and API key management.
  - name: Public
    description: >-
      Unauthenticated endpoints — market data, health checks, and account-scoped
      info reads.
  - name: Exchange
    description: >
      Signed order management endpoints (all are HTTP `POST`). Every request
      must carry the full header triple `X-API-Key` + `X-Timestamp` +
      `X-Signature` where `X-Signature` is an Ed25519 signature. `placeOrder`,
      `cancelOrder` and `modifyOrder` sign the typed canonical payload for the
      operation — a compact, key-sorted JSON object of engine-native fields, not
      the raw body. Other signed endpoints (e.g. `cancelAllOrders`,
      `setLeverage`) sign `X-Timestamp + ACTION + canonicalJSON(body)`, where
      ACTION is the path's final camelCase segment (e.g. `cancelAllOrders`) and
      the HTTP method is not signed. `X-Timestamp` is a Unix nanosecond epoch
      (decimal string) and must be within ±30,000 ms of server wall-clock. See
      the top-level **Authentication** section for full details. These endpoints
      also require query parameter `address` matching the key's master Ethereum
      address.
  - name: Referral
    description: >
      Affiliate / referral program endpoints. Mutating endpoints (`POST`)
      require the full Ed25519 signature triple and the body `address` must
      match the API key's master Ethereum address.


      Most read endpoints (`GET`) are signed too, and `?address=` must match the
      API key's master Ethereum address — so a caller only ever reads their own
      referral data. That covers `/info`, `/code`, `/referees` and
      `/commissions`. A referral code is meant to be shareable without
      disclosing the wallet behind it.


      Still public and scoped by `?address=`: `/myReferrer` (returns the
      binding's code and discount, never the referrer's address), `/claims`,
      `/claimStatus`, `/codeAvailable` (returns only whether a code is taken,
      never its owner) and `/leaderboard`.
paths:
  /v1/corporateActions/{market_id}:
    get:
      tags:
        - Public
      summary: Get corporate actions for a market
      description: >
        Returns one market's splits, reverse splits, stock dividends and cash
        dividends that are upcoming or took effect in the last 60 days, each in
        its latest status (an empty list when it has none).
      operationId: getMarketCorporateActions
      parameters:
        - name: market_id
          in: path
          required: true
          schema:
            type: string
            example: '1'
          description: >
            The numeric market id (e.g. `1`) or the display name (e.g.
            `BTC-USD`, case-insensitive). An unresolvable value → 400.
      responses:
        '200':
          description: The market's corporate actions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MarketCorporateActionsResponse'
        '400':
          description: Unknown market.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/generic-error'
        '429':
          $ref: '#/components/responses/TooManyRequests'
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl https://api.arcus.xyz/v1/corporateActions/1
            curl https://api.arcus.xyz/v1/corporateActions/BTC-USD
components:
  schemas:
    MarketCorporateActionsResponse:
      type: object
      required:
        - marketId
        - marketDisplayName
        - corporateActions
      properties:
        marketId:
          $ref: '#/components/schemas/MarketId'
        marketDisplayName:
          $ref: '#/components/schemas/MarketDisplayName'
        corporateActions:
          type: array
          description: >-
            The market's corporate actions that are upcoming or took effect in
            the last 60 days, in their latest status, soonest `effectiveTime`
            first; empty when none.
          items:
            $ref: '#/components/schemas/CorporateAction'
    generic-error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: Human-readable error message.
          examples:
            - Invalid request body
        code:
          type: string
          description: >
            Machine-readable error code for generic (non-order) rejections.
            Present on geo-restriction blocks; clients should key
            product-availability UI off this rather than the human `error`
            string.


            | Value            | Meaning |

            |------------------|---------|

            | `GEO_RESTRICTED` | The action is not available from the caller's
            country/region for this product (perps and/or spot). Reads remain
            available; only state-changing actions are blocked. |
          enum:
            - GEO_RESTRICTED
    MarketId:
      type: integer
      minimum: 0
      maximum: 65535
      description: >-
        Perpetual market identifier (uint16). Map to display name via `GET
        /markets`. Used for orders, positions, funding, and market metadata.
    MarketDisplayName:
      type: string
      description: Market symbol (e.g. BTC-USD).
      examples:
        - BTC-USD
    CorporateAction:
      type: object
      required:
        - id
        - sourceId
        - marketId
        - marketDisplayName
        - type
        - status
        - version
        - updatedAt
        - statusUpdatedAt
        - exDate
        - effectiveTime
      properties:
        id:
          type: string
          description: >
            The exchange's permanent id for this action: `CA-` and 16 base32
            characters, derived from `sourceId`. It stays the same through every
            status, date or ratio change, and no two actions share one (a second
            split on the same market gets a new id).
          examples:
            - CA-PMGAFX71TX2HJM3Y
        sourceId:
          type: string
          description: The data provider's id for this action, which `id` is derived from.
          examples:
            - ca-01m14cxqtkenq8n0qvdc3rxx2m
        marketId:
          $ref: '#/components/schemas/MarketId'
        marketDisplayName:
          $ref: '#/components/schemas/MarketDisplayName'
        type:
          $ref: '#/components/schemas/CorporateActionType'
        status:
          $ref: '#/components/schemas/CorporateActionStatus'
        version:
          type: integer
          format: uint32
          description: >
            Starts at 1 and goes up by one each time any field of the action
            changes (status, dates, ratio or amounts). Compare it with a stored
            copy to detect updates.
          examples:
            - 2
        updatedAt:
          type: string
          format: date-time
          description: When the current `version` was recorded.
          examples:
            - '2026-11-06T14:00:00Z'
        statusUpdatedAt:
          type: string
          format: date-time
          description: When the action entered its current `status`.
          examples:
            - '2026-11-06T14:00:00Z'
        exDate:
          type: string
          format: date
          description: >
            US equity ex-date (`YYYY-MM-DD`), the first trading day the price
            reflects the action. When a stock dividend has no ex-date yet, this
            is the effective date `effectiveTime` was derived from.
          examples:
            - '2026-11-20'
        effectiveTime:
          type: string
          format: date-time
          description: >
            When the action takes effect on the exchange: 20:05 New York time on
            the evening before `exDate`, when that session opens. A split with
            ex-date 2026-11-20 takes effect 2026-11-19 20:05 EST. A stock
            dividend that has no ex-date yet uses its effective date the same
            way, and that date is reported as `exDate`.
          examples:
            - '2026-11-20T01:05:00Z'
        ratioNumerator:
          type: integer
          format: uint32
          description: >
            Splits, reverse splits, and stock dividends when a ratio is
            published. New shares per `ratioDenominator` old shares: a 4-for-1
            split is `4/1`, a 1-for-10 reverse split `1/10`, a one-for-one stock
            dividend `1/1`. When the split applies, prices divide by the ratio
            and position sizes multiply by it. Omitted on a stock dividend whose
            ratio is not yet known.
          examples:
            - 8
        ratioDenominator:
          type: integer
          format: uint32
          description: >-
            Splits, reverse splits, and stock dividends when a ratio is
            published. Old shares per `ratioNumerator` new shares.
          examples:
            - 1
        grossAmount:
          type: string
          description: >-
            Cash dividends only. Dividend per share in USD before withholding
            tax, as a decimal string.
          examples:
            - '0.27'
        netAmount:
          type: string
          description: >-
            Cash dividends only, when published. Dividend per share in USD after
            published deductions.
          examples:
            - '0.2295'
        recordDate:
          type: string
          format: date
          description: Date that determines entitlement (`YYYY-MM-DD`), when known.
          examples:
            - '2026-11-13'
        payDate:
          type: string
          format: date
          description: Date holders receive the distribution (`YYYY-MM-DD`), when known.
          examples:
            - '2026-11-30'
    RateLimitedError:
      description: >
        429 response body shape. Extends the generic `Error` with two
        rate-limit-specific fields:


        - `reason` — which limiter rejected the request. Stable string enum; new
        values may be added in future versions, so clients should treat unknown
        values as opaque.

        - `retryAfterMs` — precise milliseconds the client should wait before
        retrying. The HTTP `Retry-After` header carries the same information
        rounded up to whole seconds (RFC 7231); prefer this field when
        sub-second precision matters.
      type: object
      required:
        - error
      properties:
        error:
          type: string
          example: rate limited
        reason:
          type: string
          enum:
            - ip
            - account_empty
            - account_partial
            - unknown
          description: |
            Layer that rejected the request:
              * `ip` — per-IP weight bucket exhausted.
              * `account_empty` — per-subaccount pool fully exhausted; the
                drip-throttle has no token available either.
              * `account_partial` — pool has some credit but not enough
                for this batch. Split the request into smaller chunks to
                drain the remaining headroom.
              * `unknown` — defensive fallback; clients should retry per
                `retryAfterMs` and report the occurrence.
        retryAfterMs:
          type: integer
          format: int64
          minimum: 0
          description: >-
            Milliseconds to wait before retrying. Matches the precise wait the
            rate limiter computed (the `Retry-After` header rounds up to the
            next whole second).
        clientId:
          type: string
          description: >
            Echo of the request's client-supplied `clientId`, so the client can
            correlate the rejection to a specific order request. Present only on
            single-order endpoints (placeOrder, modifyOrder, cancelOrder) when
            the request carried a `clientId`. Omitted on batch endpoints (see
            `clientIds`) and when the request had none.
        clientIds:
          type: array
          items:
            type: string
          description: >
            Echo of every client-supplied `clientId` in a batch request
            (batchPlaceOrders, batchCancelOrders), positionally aligned with the
            submitted `orders` / `cancels` array. A batch is rejected
            all-or-nothing, so every listed order was rejected; the echo lets a
            client submitting multiple batches concurrently correlate the 429 to
            a specific batch. An entry is empty when that element carried no
            `clientId` (e.g. a cancel-by-orderId). Omitted on single-order
            endpoints (see `clientId`).
    CorporateActionType:
      type: string
      enum:
        - SPLIT
        - REVERSE_SPLIT
        - CASH_DIVIDEND
        - STOCK_DIVIDEND
    CorporateActionStatus:
      type: string
      description: >
        `ANNOUNCED` → `CONFIRMED` → `APPLIED`, or `CANCELLED` when the issuer
        withdraws the action. Always the action's latest status.
      enum:
        - ANNOUNCED
        - CONFIRMED
        - APPLIED
        - CANCELLED
  responses:
    TooManyRequests:
      description: >
        Rate limit exceeded. Two signals are returned, designed to coexist with
        both naive HTTP clients and rate-limit-aware SDK clients:


        - `Retry-After` header (integer seconds, RFC 7231 compliant). Rounds up
        — clients that obey this header sleep at least as long as required. Safe
        for generic HTTP libraries to read.

        - JSON body `retryAfterMs` (precise milliseconds, matches the server's
        internal computation). Sophisticated clients should prefer this over the
        header to avoid the round-up overshoot.

        - JSON body `reason` indicates which rate-limit layer rejected: `ip`
        (per-IP weight bucket), `account_empty` (per-subaccount pool fully
        exhausted, in drip throttle), `account_partial` (pool has some credit
        but not enough for this batch — split the request smaller to drain), or
        `unknown` (defensive fallback).

        - JSON body `clientId` (single-order endpoints) or `clientIds` (batch
        endpoints) echoes the request's client-supplied order identifier(s) so
        the client can correlate the rejection to a specific order request.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/RateLimitedError'
          example:
            error: rate limited
            reason: account_empty
            retryAfterMs: 850
            clientId: my-order-42
  headers:
    RetryAfter:
      description: Seconds the client should wait before retrying the request.
      schema:
        type: integer
        minimum: 1
        example: 1

````

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