---
title: "Token locks & vesting on a mint (Streamflow, Jupiter Lock, Bonfida, Smithii, Sablier)"
method: GET
path: "/tokens/{mint}/locks"
tags: ["Tokens"]
---

# Token locks & vesting on a mint (Streamflow, Jupiter Lock, Bonfida, Smithii, Sablier)

`GET /tokens/{mint}/locks`

## Request

- Base URL: `https://madeonsol.com/api/v1`
- URL: `https://madeonsol.com/api/v1/tokens/{mint}/locks`
- Auth: HTTP bearer

Every **on-chain token lock / vesting contract** on a mint — Streamflow streams, Jupiter Lock vesting escrows and Bonfida token-vesting accounts, plus Smithii vesting and Sablier Lockup streams while they are listed in 'meta.programs' (rows are admitted only after per-account verification; Sablier's 'recipient' is the current proven stream-NFT holder or null, see 'holder_status') — decoded from the locker programs' account state (Yellowstone account subscription + daily getProgramAccounts reconciliation, mig 326). Each contract carries the schedule (start / cliff / period / end, cliff and per-period amounts), the terms (cancelable by sender/recipient, transferable, top-up) and a **live-derived** view computed at request time: what is still locked right now, what has unlocked, what is claimable, and the 'next_unlock' event. The 'summary' rolls up locked / deposited totals (raw, ui, usd, % of supply), the **7d / 30d forward unlock schedule**, the nearest next unlock across all contracts, distinct lockers and how many active contracts the sender can still cancel. Answers *did the team lock, how much, until when, and can they pull it*. **LP locks are not included** (this is token/vesting locks). Amounts are base-unit strings; ui/usd/pct are null when decimals/price are unknown ('token.facts_resolved'). PRO+.

## Path parameters

- `mint` string, required

## Query parameters

- `status` 'active' | 'completed' | 'cancelled' | 'closed'
- `program` 'streamflow' | 'jupiter_lock' | 'bonfida_vesting' | 'smithii_vesting' | 'sablier_lockup'
- `limit` integer

## Response `200`

OK

- object
  - `mint` string
  - `token` object
    - `symbol` string, nullable
    - `name` string, nullable
    - `decimals` integer, nullable
    - `price_usd` number, nullable
    - `supply` number, nullable
    - `market_cap_usd` number, nullable
    - `facts_resolved` boolean
  - `summary` object
    - `lock_count` integer: Exact count of contracts on the mint
    - `complete` boolean: false when the mint holds more than 5000 contracts — totals then cover the newest 5000 (rows_considered)
    - `rows_considered` integer
    - `active_count` integer
    - `by_program` object
    - `by_kind` object
    - `distinct_lockers` integer
    - `locked_raw` string
    - `locked` number, nullable
    - `locked_usd` number, nullable
    - `locked_pct_of_supply` number, nullable
    - `deposited_raw` string
    - `deposited` number, nullable
    - `deposited_usd` number, nullable
    - `unlocking_7d_raw` string
    - `unlocking_7d` number, nullable
    - `unlocking_7d_usd` number, nullable
    - `unlocking_7d_pct_of_supply` number, nullable
    - `unlocking_30d_raw` string
    - `unlocking_30d` number, nullable
    - `unlocking_30d_usd` number, nullable
    - `unlocking_30d_pct_of_supply` number, nullable
    - `next_unlock` object, nullable
      - `at` string, date-time
      - `kind` string
      - `amount_raw` string
      - `amount` number, nullable
      - `amount_usd` number, nullable
      - `lock_account` string
    - `active_cancelable_by_sender` integer
  - `locks` object[]
    - `lock_account` string: The contract account (Streamflow stream / Jupiter VestingEscrow / Bonfida vesting account)
    - `program` 'streamflow' | 'jupiter_lock' | 'bonfida_vesting' | 'smithii_vesting' | 'sablier_lockup'
    - `provider` object: Who runs the lock contract, and how sure we are. identity: verified = a known provider deployment (by contract address); compatible = only the event shape (ABI) matches a known provider, the operator is NOT identified; unverified = unknown. id/website_url are null unless verified. lock_url is a per-lock page on the provider's site, emitted ONLY where the URL format is proven (none is proven for Streamflow / Jupiter Lock / Bonfida today, so it is always null); otherwise null (never guessed).
      - `id` string, nullable
      - `name` string, nullable
      - `identity` 'verified' | 'compatible' | 'unverified'
      - `compatible_with` string, nullable
      - `website_url` string, nullable
      - `lock_url` string, nullable
    - `explorer` object: Independent evidence on Solana Explorer.
      - `lock_account_url` string, nullable
      - `creation_tx_url` string, nullable
    - `price_usd` number, nullable: Token price used for the *_usd fields (null when unknown or guarded as phantom).
    - `seconds_until_end` integer, nullable: Seconds until fully unlocked (>= 0). 0 once completed; null when there is no end date (perpetual) or the lock was cancelled/closed.
    - `seconds_until_next_unlock` integer, nullable: Seconds until next_unlock.at (>= 0); null when there is no next unlock.
    - `kind` 'lock' | 'vesting': lock = whole amount at one date; vesting = cliff and/or periodic release
    - `status` 'active' | 'completed' | 'cancelled' | 'closed': Derived at request time
    - `mint` string
    - `sender` string, nullable: Creator / locker (Bonfida has none on-chain)
    - `recipient` string, nullable: Beneficiary. sablier_lockup: the CURRENT proven holder of the stream NFT only; null when the holder is not currently proven (see holder_status), never the last proven holder. smithii_vesting: the authority for single-receiver locks, null for merkle receivers (off-chain).
    - `holder_status` 'current' | 'lost_proof' | 'never_proven' | 'burned' | 'anomaly' | 'null', nullable: sablier_lockup only (null for other programs): current = recipient proven by the latest read; lost_proof = recipient unknown, last_proven_holder is evidence; never_proven; burned = stream NFT burned, no recipient; anomaly = fail closed.
    - `last_proven_holder` string, nullable: sablier_lockup only: the last holder a verifying read proved (provenance, NOT the current recipient unless holder_status is current).
    - `holder_proven_at_slot` integer, nullable: sablier_lockup only: slot of the read that last proved last_proven_holder.
    - `name` string, nullable
    - `amount_raw` string
    - `amount` number, nullable
    - `amount_usd` number, nullable
    - `amount_pct_of_supply` number, nullable
    - `locked_raw` string: Still locked right now (amount − unlocked-so-far); 0 unless active
    - `locked` number, nullable
    - `locked_usd` number, nullable
    - `locked_pct_of_supply` number, nullable
    - `unlocked_raw` string
    - `unlocked` number, nullable
    - `withdrawn_raw` string, nullable: Claimed so far; null when the program does not expose it (withdrawn_tracked false: smithii_vesting)
    - `withdrawn` number, nullable
    - `withdrawn_tracked` boolean: false = withdrawn/claimable are unknown (null), not zero
    - `claimable_raw` string, nullable: Unlocked but not yet withdrawn; null when withdrawn is not tracked
    - `claimable` number, nullable
    - `start_at` string, date-time, nullable
    - `cliff_at` string, date-time, nullable
    - `end_at` string, date-time, nullable: Fully unlocked at; null = perpetual/no schedule
    - `period_seconds` integer, nullable
    - `continuous` boolean: period < 1h (per-second stream)
    - `amount_per_period_raw` string, nullable
    - `amount_per_period` number, nullable
    - `cliff_amount_raw` string, nullable
    - `cliff_amount` number, nullable
    - `perpetual` boolean
    - `schedule` object[]: Bonfida token-vesting only (absent on Streamflow / Jupiter Lock): the tranche list, each { release_at, amount_raw } with amount_raw a base-unit string.
      - `release_at` string, date-time, nullable
      - `amount_raw` string
    - `next_unlock` object, nullable
      - `at` string, date-time
      - `kind` 'cliff' | 'period' | 'final' | 'tranche'
      - `amount_raw` string
      - `amount` number, nullable
      - `amount_usd` number, nullable
    - `cancelable_by_sender` boolean, nullable: The locker can cancel — funds are locked against the recipient, not the locker
    - `cancelable_by_recipient` boolean, nullable
    - `transferable` boolean, nullable
    - `can_topup` boolean, nullable
    - `cancelled_at` string, date-time, nullable
    - `created_at` string, date-time, nullable
    - `created_at_estimated` boolean: Backfilled row with no on-chain creation time (Jupiter Lock)
    - `tx_signature` string, nullable
  - `meta` object

## Other responses

- `400`: Invalid mint or query parameters
- `401`: Missing or invalid API key, or an expired free-tier key. Authentication-stage error: no `X-RateLimit-*` headers, no `_rid`.
- `403`: Forbidden. One of: the key's tier is below this endpoint's or parameter's gate (`tier_required` with an `upgrade` block); the public demo key used outside its allow-list (`demo_key_endpoint_not_allowed`); an invalid or revoked key; an origin-restricted key called from a disallowed origin (`code` `origin_not_allowed` / `origin_required`). `X-RateLimit-*` headers are present only on `tier_required`.
- `429`: Too many requests. Every 429 carries `Retry-After`. A quota 429 (`rate_limit_exceeded`, with `X-RateLimit-*`), a heavy-query concurrency 429 (`error_kind` `concurrency`/`capacity`), or the per-IP authentication-failure block (30 failed auths/min; plain `error` + `retry_after_seconds`, no `X-RateLimit-*`).
- `500`: Unexpected server error from the route (`Internal server error`, with `_rid`). Safe to retry with backoff. A failed API-key lookup is a 503 `auth_backend_unavailable`, never a 500.
- `503`: Temporarily unavailable — a Postgres statement timeout while the dataset is under load or maintenance (`statement_timeout`, with `X-RateLimit-*` and `_rid`), or the API-key lookup itself unavailable (`auth_backend_unavailable`, authentication stage: no `X-RateLimit-*`, no `_rid`, not counted as a failed authentication). Always carries `Retry-After`; honour it.

---

[API](https://skmtc.dev/madeonsol/apis/madeonsol-api.md) · [All operations](https://skmtc.dev/madeonsol/apis/madeonsol-api/llms.txt) · [OpenAPI document](https://skmtc.dev/madeonsol/apis/madeonsol-api/revisions/96ce84657f55?raw)
