Skip to content

Fume API Reference

Endpoints, parameters and response shapes of the public Fume API: the tokenized fund registry, the fund service provider catalog, and the site's submission endpoints.

The machine-readable version of this page is the OpenAPI 3.1 document at /openapi.json (mirrored at /api/openapi.json). It is the source of truth; this page is the readable summary.

Base URL: https://www.fume.finance. No authentication. Read endpoints allow any origin and are cached at the edge for an hour.

Versioning and deprecation

Every endpoint below is served under /api/v1/. The unprefixed form β€” /api/registry/funds β€” is a permanent alias for the current major version and returns the same response, so an integration written against it keeps working; new ones should pin the versioned path.

Every response from a published endpoint states the contract it was served under. API-Version: 1 names the major version in a header, so a client holding a response but not the URL it called can still tell. Two RFC 8631 Link relations travel with it β€” service-desc pointing at /openapi.json and service-doc at this page β€” so any response, including an error, carries the way back to both descriptions.

A breaking change means a new major version under a new prefix; /api/v1/ keeps answering. Additive changes β€” a new field, a new optional parameter, a new endpoint β€” ship without a version bump, so parse responses tolerantly and ignore fields you do not know. An endpoint retired within a version gets 90 days of notice, announced with RFC 9745 Deprecation and RFC 8594 Sunset headers. The full stability contract β€” what counts as breaking, and what a retirement looks like on the wire β€” is the API versioning and deprecation policy.

Read the tokenized fund registry

GET /api/v1/registry/funds

Lists the funds in the Tokenized Fund Registry with strategy, AUM, chain, token standard, fees, jurisdiction and named service providers.

ParameterTypeNotes
chainstringExact match, case-insensitive. Ethereum, Base, …
statusstringOpen, Closed, Upcoming, Soft Close, Hard Close, Launching
assetClassstringExact match, case-insensitive
jurisdictionstringExact match, case-insensitive
qstringSubstring search over name, manager, issuer, strategy, description
limitintegerDefault 50, max 200. Out-of-range values are clamped, not rejected
offsetintegerDefault 0
cursorstringA nextCursor from a previous response. Takes precedence over offset
curl -s "https://www.fume.finance/api/v1/registry/funds?chain=Base&status=Open&limit=5" | jq '.total, .funds[].name'

Returns { total, limit, offset, nextCursor, funds[] }. Every fund carries url, the canonical page to cite, and dataSource, which says whether the record was verified onchain, taken from a public filing, or self-reported.

GET /api/v1/registry/funds/{id}

One fund by its registry slug β€” the same slug as /registry/{id}.

curl -s https://www.fume.finance/api/v1/registry/funds/blackrock-buidl | jq .name

Unknown ids return 404 with code: "fund_not_found".

Read the fund service provider catalog

GET /api/v1/fund-builder/providers

Every provider listed in Fund Builder: legal counsel, fund administrators, custody, exchanges and brokers, auditors, management companies and insurance.

ParameterTypeNotes
categorystringlegal, fund-admin, custody, broker, auditor, aifm, insurance
qstringSubstring search over name, description, specialty, tags, jurisdictions
limitintegerDefault 100, max 200
offsetintegerDefault 0
cursorstringA nextCursor from a previous response. Takes precedence over offset
curl -s "https://www.fume.finance/api/v1/fund-builder/providers?category=custody" | jq '.providers[].name'

Returns { total, limit, offset, nextCursor, categories[], providers[] }. The categories array is always the full list, so one call is enough to discover every valid category value.

GET /api/v1/fund-builder/providers/{id}

One provider by its catalog slug. Unknown ids return 404 with code: "provider_not_found".

Page a list

Both list endpoints page two ways. limit/offset still work and are not going anywhere. cursor is the one to prefer: every list response carries a nextCursor, and passing it back verbatim gets the next page without arithmetic.

# Follow the cursor to the end of the registry.
next=""
while :; do
  page=$(curl -s "https://www.fume.finance/api/v1/registry/funds?limit=25${next:+&cursor=$next}")
  echo "$page" | jq -r '.funds[].id'
  next=$(echo "$page" | jq -r '.nextCursor // empty')
  [ -n "$next" ] || break
done

nextCursor is null on the last page β€” that, not a count comparison, is how you know to stop. The token is opaque: pass it back as you got it rather than decoding it, because what it encodes is free to change. A token this API did not issue is rejected with 400, never silently treated as "start again", so a follow-the-cursor loop cannot spin forever.

Read several records at once

POST /api/v1/batch

Answers up to 25 read paths in one round trip. Each entry names the same path you would call on its own, so there is no second vocabulary to learn.

curl -s https://www.fume.finance/api/v1/batch \
  -H 'Content-Type: application/json' \
  -d '{"operations":[
        {"id":"base-funds","path":"/api/v1/registry/funds?chain=Base&limit=5"},
        {"id":"ogier","path":"/api/v1/fund-builder/providers/ogier"}
      ]}' | jq '.results[] | {id, status}'

Batchable paths are /api/v1/registry/funds, /api/v1/registry/funds/{id}, /api/v1/fund-builder/providers and /api/v1/fund-builder/providers/{id}; the /api/v1 prefix may be omitted. Give each operation an id and it comes back on the matching result, so you need not rely on array order.

A 200 means every operation was attempted, not that every one was found β€” each result carries its own status, and a failed entry carries the same error body that read would have returned on its own. A list read inside a batch returns at most 50 records whatever limit it asks for; page deeper with the cursor on the endpoint itself. The request itself is rejected with 400 only if the body is not JSON, operations is missing or empty, or it carries more than 25 entries.

Search the documentation

GET /api/v1/search?query=…

Full-text search over /docs, returning ranked page, heading and text fragments. For bulk ingestion prefer /llms-full.txt, which is the entire corpus in one request.

Submission endpoints

These deliver a message to the Fume team. They accept POST with a JSON body and return { "success": true }.

EndpointRequired fields
/api/v1/contactname, email, message
/api/v1/newsletteremail
/api/v1/consulting-inquiryname, email
/api/v1/fund-builder/stack-submissionemail
/api/v1/fund-builder/introduction-requestemail, providerName
/api/v1/fund-builder/partner-listingcompanyName, email, category
/api/v1/registry/document-requestfundId, name, email
/api/v1/registry/list-fundfundName, contactName, email, strategy, chain

In production each one also requires a captchaToken β€” a Google reCAPTCHA v3 token, which only a browser session can produce. They exist for the forms on this site. If you are an agent trying to reach us, email info@fume.finance. The full field list for each endpoint is in /openapi.json.

Status codes

StatuscodeMeaning
400missing_required_fieldA required field was absent
400invalid_emailThe email field is not a valid address
400invalid_jsonThe body did not parse as JSON
404fund_not_found / provider_not_foundNo record with that id
404unknown_endpointNo such endpoint under /api
405method_not_allowedWrong method; the Allow header names the right one
429rate_limitedOver 120 requests in 60 seconds; wait Retry-After seconds
500upstream_errorThe request was fine, a downstream service was not. Retry

Every one of them returns the same JSON envelope described in the developer overview.

Rate limits

Every endpoint on this page is limited to 120 requests per 60 seconds per client address. There is no key and no signup: each response states the budget it was served against in RateLimit (limit=120, remaining=118, reset=54, where reset counts seconds until the window clears), restates the policy in RateLimit-Policy, and repeats both as X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. The count is kept by the instance that answered rather than in a shared store, so read it as a ceiling, not an exact ledger.