{"openapi":"3.1.0","info":{"title":"Fume Public API","version":"1.0.0","summary":"Read the Fume tokenized fund registry and fund service provider catalog, and submit the website's contact, listing and introduction requests.","description":"The public HTTP surface of fume.finance, operated by FumeX AG (Locarno, Switzerland).\n\nTwo kinds of endpoint:\n\n1. **Read endpoints** (`GET`) return the same catalog data the website renders: the Tokenized Fund Registry and the fund service provider directory. They are unauthenticated, cacheable, CORS-open, and safe for an agent to call directly.\n2. **Submission endpoints** (`POST`) hand a message to the Fume team (contact, newsletter, provider introduction, registry listing, fund stack PDF). They are unauthenticated but captcha-gated: production requires a Google reCAPTCHA v3 token in `captchaToken`, so they are meant to be called by the website's own forms. An agent that needs to reach the team should email info@fume.finance instead.\n\nEvery error, on every endpoint and every status code, uses the same JSON envelope: `error`, `code`, `message`, `hint`, `status`, `docs`. Branch on `code`; show `message`; follow `hint` to recover.\n\nNo endpoint requires authentication, and there are no API keys to obtain. Rate limits are the Vercel platform defaults; the read endpoints are cached at the edge, so polling more than once an hour returns cached data.\n\nNot described here: `POST /api/calcom-booking` (an internal Cal.com webhook receiver that relays to the Fume CRM) and `GET /api/search/investorfaq` (search over link-only investor content). Neither is part of the public product surface.","termsOfService":"https://www.fume.finance/terms-and-conditions","contact":{"name":"Fume","email":"info@fume.finance","url":"https://www.fume.finance/resources/contact-us"},"license":{"name":"Proprietary","url":"https://www.fume.finance/terms-and-conditions"}},"servers":[{"url":"https://www.fume.finance","description":"Production"}],"externalDocs":{"description":"Fume developer and agent resources","url":"https://www.fume.finance/docs/developers"},"tags":[{"name":"Registry","description":"The Tokenized Fund Registry: a public list of tokenized investment funds with onchain proofs.","externalDocs":{"url":"https://www.fume.finance/registry"}},{"name":"Fund Builder","description":"The fund service provider catalog: legal, fund admin, custody, exchange/broker, audit, management company and insurance providers.","externalDocs":{"url":"https://www.fume.finance/fund-builder"}},{"name":"Contact","description":"Endpoints that deliver a message to the Fume team.","externalDocs":{"url":"https://www.fume.finance/resources/contact-us"}},{"name":"Search","description":"Full-text search over the Fume documentation."},{"name":"Media","description":"Dynamically rendered Open Graph share images."}],"paths":{"/api/registry/funds":{"get":{"operationId":"listRegistryFunds","summary":"List tokenized funds in the Fume registry","description":"Returns the tokenized investment funds listed in the Fume Tokenized Fund Registry, with strategy, AUM, chain, token standard, fees, jurisdiction and service providers for each. Same records the /registry pages render. Filters combine with AND; unknown filter values simply match nothing.","tags":["Registry"],"parameters":[{"name":"chain","in":"query","required":false,"description":"Settlement chain, case-insensitive. Most funds settle on several chains, and a fund matches if any one of its chains equals this value (e.g. \"Ethereum\", \"Base\", \"Arbitrum\").","schema":{"type":"string"},"example":"Base"},{"name":"status","in":"query","required":false,"description":"Subscription status of the fund.","schema":{"type":"string","enum":["Open","Closed","Upcoming","Soft Close","Hard Close","Launching"]},"example":"Open"},{"name":"assetClass","in":"query","required":false,"description":"Exact asset class, case-insensitive (e.g. \"Digital Assets\", \"Private Credit\").","schema":{"type":"string"}},{"name":"jurisdiction","in":"query","required":false,"description":"Exact fund domicile, case-insensitive (e.g. \"Cayman Islands\", \"Luxembourg\").","schema":{"type":"string"}},{"name":"q","in":"query","required":false,"description":"Case-insensitive substring search over fund name, manager, issuer, strategy and description.","schema":{"type":"string"},"example":"money market"},{"name":"limit","in":"query","required":false,"description":"Maximum number of funds to return. Out-of-range values are clamped, not rejected.","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"offset","in":"query","required":false,"description":"Number of matching funds to skip, for paging through `total`.","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"The matching funds, newest listing order preserved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FundList"}}}},"405":{"description":"Method not allowed. This endpoint accepts GET.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/registry/funds/{id}":{"get":{"operationId":"getRegistryFund","summary":"Get one registry fund by id","description":"Returns a single tokenized fund by its registry slug. The slug is the same one used by the human-readable page at /registry/{id} and by the `id` field of every record in listRegistryFunds.","tags":["Registry"],"parameters":[{"name":"id","in":"path","required":true,"description":"Registry slug of the fund, e.g. \"acquinox-capital-fund\".","schema":{"type":"string"}}],"responses":{"200":{"description":"The fund record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Fund"}}}},"404":{"description":"No fund with that id. List the valid ids with listRegistryFunds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Method not allowed. This endpoint accepts GET.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/fund-builder/providers":{"get":{"operationId":"listFundServiceProviders","summary":"List fund service providers in the Fume catalog","description":"Returns every fund service provider Fume lists — legal counsel, fund administrators, custodians, exchanges/brokers, auditors, management companies and insurance — with jurisdictions, specialty, indicative pricing and the canonical page URL. The response also carries the category list, so the valid `category` values are discoverable without a second call.","tags":["Fund Builder"],"parameters":[{"name":"category","in":"query","required":false,"description":"Restrict to one category.","schema":{"type":"string","enum":["legal","fund-admin","custody","broker","auditor","aifm","insurance"]},"example":"custody"},{"name":"q","in":"query","required":false,"description":"Case-insensitive substring search over provider name, description, specialty, tags and jurisdictions.","schema":{"type":"string"},"example":"cayman"},{"name":"limit","in":"query","required":false,"description":"Maximum number of providers to return. Out-of-range values are clamped, not rejected.","schema":{"type":"integer","minimum":1,"maximum":200,"default":100}},{"name":"offset","in":"query","required":false,"description":"Number of matching providers to skip, for paging through `total`.","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"The matching providers plus the full category list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderList"}}}},"405":{"description":"Method not allowed. This endpoint accepts GET.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/fund-builder/providers/{id}":{"get":{"operationId":"getFundServiceProvider","summary":"Get one fund service provider by id","description":"Returns a single provider by its catalog slug, including the long description shown on /fund-builder/providers/{id}.","tags":["Fund Builder"],"parameters":[{"name":"id","in":"path","required":true,"description":"Provider slug, e.g. \"ogier\".","schema":{"type":"string"}}],"responses":{"200":{"description":"The provider record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Provider"}}}},"404":{"description":"No provider with that id. List the valid ids with listFundServiceProviders.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Method not allowed. This endpoint accepts GET.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/contact":{"post":{"operationId":"submitContactMessage","summary":"Send a message to the Fume team","description":"Delivers a free-text message from the website contact form to the Fume team, with the sender's address set as reply-to. Nothing is stored server-side beyond the resulting email.","tags":["Contact"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["name","email","message"],"properties":{"name":{"type":"string","description":"Sender's full name."},"email":{"type":"string","format":"email","description":"Reply-to address for the request."},"message":{"type":"string","description":"The message body. Plain text; newlines are preserved."},"captchaToken":{"type":"string","description":"Google reCAPTCHA v3 token. Required whenever the deployment has RECAPTCHA_SECRET_KEY configured (it is, in production), which means these write endpoints are reachable from the website's own forms in a browser and not from an unattended agent. A request without a valid token is rejected with 400 `captcha_required` / `captcha_failed`."}}}}}},"responses":{"200":{"description":"The message was accepted and delivered to the Fume team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmissionAccepted"}}}},"400":{"description":"A required field is missing, the email is malformed, the JSON is invalid, or the captcha token was rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Method not allowed. This endpoint accepts POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The message was well-formed but the email provider failed. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"submitContactMessageMethodNotAllowed","summary":"Not allowed — this endpoint is POST-only","description":"Returns 405 with the standard error envelope naming the allowed method. Documented so an agent that probes with GET can recognise the response instead of treating the empty default 405 as a broken endpoint.","tags":["Contact"],"responses":{"405":{"description":"Method not allowed. Retry with POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/newsletter":{"post":{"operationId":"subscribeToNewsletter","summary":"Subscribe an address to the Fume newsletter","description":"Adds the address to the Fume leads newsletter and notifies the team. Repeat signups succeed: the contact record is upserted.","tags":["Contact"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["email"],"properties":{"email":{"type":"string","format":"email","description":"Address to subscribe."},"captchaToken":{"type":"string","description":"Google reCAPTCHA v3 token. Required whenever the deployment has RECAPTCHA_SECRET_KEY configured (it is, in production), which means these write endpoints are reachable from the website's own forms in a browser and not from an unattended agent. A request without a valid token is rejected with 400 `captcha_required` / `captcha_failed`."}}}}}},"responses":{"200":{"description":"The message was accepted and delivered to the Fume team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmissionAccepted"}}}},"400":{"description":"A required field is missing, the email is malformed, the JSON is invalid, or the captcha token was rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Method not allowed. This endpoint accepts POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The message was well-formed but the email provider failed. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"subscribeToNewsletterMethodNotAllowed","summary":"Not allowed — this endpoint is POST-only","description":"Returns 405 with the standard error envelope naming the allowed method. Documented so an agent that probes with GET can recognise the response instead of treating the empty default 405 as a broken endpoint.","tags":["Contact"],"responses":{"405":{"description":"Method not allowed. Retry with POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/consulting-inquiry":{"post":{"operationId":"submitConsultingInquiry","summary":"Send a qualified inquiry from the homepage questionnaire","description":"Delivers an inquiry that names which fund-operations pain points the sender selected on the homepage questionnaire. Pain point ids outside the published set are dropped rather than rejected.","tags":["Contact"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["name","email"],"properties":{"name":{"type":"string","description":"Sender's full name."},"email":{"type":"string","format":"email","description":"Reply-to address for the request."},"company":{"type":"string","description":"Sender's firm."},"painPoints":{"type":"array","items":{"type":"string"},"description":"Ids of the fund-operations pain points selected on the questionnaire. Unrecognised ids are ignored."},"message":{"type":"string","description":"Optional free-text note."},"captchaToken":{"type":"string","description":"Google reCAPTCHA v3 token. Required whenever the deployment has RECAPTCHA_SECRET_KEY configured (it is, in production), which means these write endpoints are reachable from the website's own forms in a browser and not from an unattended agent. A request without a valid token is rejected with 400 `captcha_required` / `captcha_failed`."}}}}}},"responses":{"200":{"description":"The message was accepted and delivered to the Fume team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmissionAccepted"}}}},"400":{"description":"A required field is missing, the email is malformed, the JSON is invalid, or the captcha token was rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Method not allowed. This endpoint accepts POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The message was well-formed but the email provider failed. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"submitConsultingInquiryMethodNotAllowed","summary":"Not allowed — this endpoint is POST-only","description":"Returns 405 with the standard error envelope naming the allowed method. Documented so an agent that probes with GET can recognise the response instead of treating the empty default 405 as a broken endpoint.","tags":["Contact"],"responses":{"405":{"description":"Method not allowed. Retry with POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/fund-builder/stack-submission":{"post":{"operationId":"requestFundStackPdf","summary":"Email a one-page PDF of an assembled fund stack","description":"Renders the provider stack assembled in the Fund Builder as a one-page PDF, emails it to the requester, and notifies the Fume team. Provider ids come from listFundServiceProviders.","tags":["Fund Builder"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["email"],"properties":{"email":{"type":"string","format":"email","description":"Where to send the PDF."},"stack":{"type":"object","additionalProperties":{"type":"string"},"description":"Map of category id (legal, fund-admin, custody, broker, auditor, aifm, insurance) to provider id, as returned by listFundServiceProviders.","example":{"legal":"ogier","custody":"copper"}},"legalForm":{"type":"string","description":"Recommended legal structure to print on the PDF, e.g. \"Cayman SPC\"."},"wantIntros":{"type":"boolean","description":"Whether the requester wants warm introductions to the selected providers."},"captchaToken":{"type":"string","description":"Google reCAPTCHA v3 token. Required whenever the deployment has RECAPTCHA_SECRET_KEY configured (it is, in production), which means these write endpoints are reachable from the website's own forms in a browser and not from an unattended agent. A request without a valid token is rejected with 400 `captcha_required` / `captcha_failed`."}}}}}},"responses":{"200":{"description":"The message was accepted and delivered to the Fume team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmissionAccepted"}}}},"400":{"description":"A required field is missing, the email is malformed, the JSON is invalid, or the captcha token was rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Method not allowed. This endpoint accepts POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The message was well-formed but the email provider failed. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"requestFundStackPdfMethodNotAllowed","summary":"Not allowed — this endpoint is POST-only","description":"Returns 405 with the standard error envelope naming the allowed method. Documented so an agent that probes with GET can recognise the response instead of treating the empty default 405 as a broken endpoint.","tags":["Fund Builder"],"responses":{"405":{"description":"Method not allowed. Retry with POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/fund-builder/introduction-request":{"post":{"operationId":"requestProviderIntroduction","summary":"Request an introduction to a fund service provider","description":"Asks the Fume team to introduce the requester to one provider from the catalog, carrying the rest of the assembled stack as context.","tags":["Fund Builder"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["email","providerName"],"properties":{"email":{"type":"string","format":"email","description":"Reply-to address for the request."},"providerName":{"type":"string","description":"Display name of the provider, as returned by listFundServiceProviders."},"categoryName":{"type":"string","description":"Display name of the provider's category."},"name":{"type":"string","description":"Requester's full name."},"context":{"type":"string","description":"What the requester wants from the provider."},"stack":{"type":"object","additionalProperties":{"type":"string"},"description":"Map of role label to provider name, giving the team the rest of the fund stack."},"captchaToken":{"type":"string","description":"Google reCAPTCHA v3 token. Required whenever the deployment has RECAPTCHA_SECRET_KEY configured (it is, in production), which means these write endpoints are reachable from the website's own forms in a browser and not from an unattended agent. A request without a valid token is rejected with 400 `captcha_required` / `captcha_failed`."}}}}}},"responses":{"200":{"description":"The message was accepted and delivered to the Fume team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmissionAccepted"}}}},"400":{"description":"A required field is missing, the email is malformed, the JSON is invalid, or the captcha token was rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Method not allowed. This endpoint accepts POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The message was well-formed but the email provider failed. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"requestProviderIntroductionMethodNotAllowed","summary":"Not allowed — this endpoint is POST-only","description":"Returns 405 with the standard error envelope naming the allowed method. Documented so an agent that probes with GET can recognise the response instead of treating the empty default 405 as a broken endpoint.","tags":["Fund Builder"],"responses":{"405":{"description":"Method not allowed. Retry with POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/fund-builder/partner-listing":{"post":{"operationId":"applyForPartnerListing","summary":"Apply to be listed in the fund service provider catalog","description":"Submits a company's application to appear in the Fume provider directory. Listings are reviewed by hand; the response only confirms the application was delivered.","tags":["Fund Builder"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["companyName","email","category"],"properties":{"companyName":{"type":"string","description":"Legal or trading name of the applying company."},"contactName":{"type":"string","description":"Name of the person to reply to."},"email":{"type":"string","format":"email","description":"Reply-to address for the request."},"website":{"type":"string","format":"uri","description":"Company website."},"category":{"type":"string","description":"Which catalog category the company belongs in. These are the display labels the listing form offers, not the catalog ids used by listFundServiceProviders.","enum":["Legal Counsel","Fund Administrator","Custody","Exchange","Auditor","ManCo","Other"]},"description":{"type":"string","description":"What the company does, in the applicant's own words."},"captchaToken":{"type":"string","description":"Google reCAPTCHA v3 token. Required whenever the deployment has RECAPTCHA_SECRET_KEY configured (it is, in production), which means these write endpoints are reachable from the website's own forms in a browser and not from an unattended agent. A request without a valid token is rejected with 400 `captcha_required` / `captcha_failed`."}}}}}},"responses":{"200":{"description":"The message was accepted and delivered to the Fume team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmissionAccepted"}}}},"400":{"description":"A required field is missing, the email is malformed, the JSON is invalid, or the captcha token was rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Method not allowed. This endpoint accepts POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The message was well-formed but the email provider failed. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"applyForPartnerListingMethodNotAllowed","summary":"Not allowed — this endpoint is POST-only","description":"Returns 405 with the standard error envelope naming the allowed method. Documented so an agent that probes with GET can recognise the response instead of treating the empty default 405 as a broken endpoint.","tags":["Fund Builder"],"responses":{"405":{"description":"Method not allowed. Retry with POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/registry/document-request":{"post":{"operationId":"requestFundDocuments","summary":"Request the offering documents of a registry fund","description":"Forwards a documentation request to the fund manager (and to the Fume team) for one fund in the registry. Fume does not verify investor status; the manager runs their own KYC/AML before sharing anything.","tags":["Registry"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["fundId","name","email"],"properties":{"fundId":{"type":"string","description":"Registry slug of the fund, as returned by listRegistryFunds."},"fundName":{"type":"string","description":"Display name of the fund, for the notification subject."},"name":{"type":"string","description":"Requester's full name."},"email":{"type":"string","format":"email","description":"Reply-to address for the request."},"captchaToken":{"type":"string","description":"Google reCAPTCHA v3 token. Required whenever the deployment has RECAPTCHA_SECRET_KEY configured (it is, in production), which means these write endpoints are reachable from the website's own forms in a browser and not from an unattended agent. A request without a valid token is rejected with 400 `captcha_required` / `captcha_failed`."}}}}}},"responses":{"200":{"description":"The message was accepted and delivered to the Fume team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmissionAccepted"}}}},"400":{"description":"A required field is missing, the email is malformed, the JSON is invalid, or the captcha token was rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Method not allowed. This endpoint accepts POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The message was well-formed but the email provider failed. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"requestFundDocumentsMethodNotAllowed","summary":"Not allowed — this endpoint is POST-only","description":"Returns 405 with the standard error envelope naming the allowed method. Documented so an agent that probes with GET can recognise the response instead of treating the empty default 405 as a broken endpoint.","tags":["Registry"],"responses":{"405":{"description":"Method not allowed. Retry with POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/registry/list-fund":{"post":{"operationId":"submitRegistryListing","summary":"Apply to list a tokenized fund in the registry","description":"Submits a tokenized fund for inclusion in the Tokenized Fund Registry. Listings are reviewed and verified by hand before they appear, so a 200 confirms delivery, not publication.","tags":["Registry"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["fundName","contactName","email","strategy","chain"],"properties":{"fundName":{"type":"string","description":"Name of the fund."},"contactName":{"type":"string","description":"Name of the person to reply to."},"email":{"type":"string","format":"email","description":"Reply-to address for the request."},"website":{"type":"string","format":"uri","description":"Fund or manager website."},"strategy":{"type":"string","description":"Investment strategy, e.g. \"Market neutral\"."},"chain":{"type":"string","description":"Chain the shares are issued on, e.g. \"Ethereum\"."},"aum":{"type":"string","description":"Assets under management, as the applicant states them."},"jurisdiction":{"type":"string","description":"Fund domicile."},"assetClass":{"type":"string","description":"Asset class of the fund."},"tokenizationPlatform":{"type":"string","description":"Platform that issued the tokenized shares."},"tokenStandard":{"type":"string","description":"Token standard, e.g. \"ERC-6909\"."},"contractAddress":{"type":"string","description":"Share token contract address."},"fundStatus":{"type":"string","description":"Whether the fund is open to subscriptions."},"managementFee":{"type":"string","description":"Management fee."},"performanceFee":{"type":"string","description":"Performance fee."},"hurdleRate":{"type":"string","description":"Hurdle rate, if any."},"highWaterMark":{"type":"string","description":"Whether a high-water mark applies."},"lockupPeriod":{"type":"string","description":"Lock-up period."},"minimumInvestment":{"type":"string","description":"Minimum subscription."},"fundAdmin":{"type":"string","description":"Fund administrator."},"auditor":{"type":"string","description":"Auditor."},"legalCounsel":{"type":"string","description":"Legal counsel."},"custodian":{"type":"string","description":"Custodian."},"notes":{"type":"string","description":"Anything else the applicant wants the reviewers to know."},"captchaToken":{"type":"string","description":"Google reCAPTCHA v3 token. Required whenever the deployment has RECAPTCHA_SECRET_KEY configured (it is, in production), which means these write endpoints are reachable from the website's own forms in a browser and not from an unattended agent. A request without a valid token is rejected with 400 `captcha_required` / `captcha_failed`."}}}}}},"responses":{"200":{"description":"The message was accepted and delivered to the Fume team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmissionAccepted"}}}},"400":{"description":"A required field is missing, the email is malformed, the JSON is invalid, or the captcha token was rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Method not allowed. This endpoint accepts POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The message was well-formed but the email provider failed. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"submitRegistryListingMethodNotAllowed","summary":"Not allowed — this endpoint is POST-only","description":"Returns 405 with the standard error envelope naming the allowed method. Documented so an agent that probes with GET can recognise the response instead of treating the empty default 405 as a broken endpoint.","tags":["Registry"],"responses":{"405":{"description":"Method not allowed. Retry with POST.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/search":{"get":{"operationId":"searchDocumentation","summary":"Full-text search over the Fume documentation","description":"Searches the /docs content (AI agents, tokenization whitepaper and user guides, OmniClear, company). Backed by the fumadocs static search index. Returns the matching headings and content fragments with the URL of each page. Prefer /llms-full.txt when you want the whole corpus in one request instead of ranked fragments.","tags":["Search"],"parameters":[{"name":"query","in":"query","required":true,"description":"Search terms.","schema":{"type":"string"},"example":"NAV automation"}],"responses":{"200":{"description":"Ranked search results.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SearchResult"}}}}}}}},"/api/registry/og":{"get":{"operationId":"renderRegistryOgImage","summary":"Render the share image for a registry fund","description":"Renders a 1200x630 PNG Open Graph card for one registry fund. Used by the metadata of /registry/{id}; documented so a crawler can attribute the image rather than treat it as an unknown endpoint.","tags":["Media"],"parameters":[{"name":"name","in":"query","required":true,"description":"Fund name to print on the card.","schema":{"type":"string"}},{"name":"aum","in":"query","required":false,"description":"AUM string to print on the card.","schema":{"type":"string"}},{"name":"strategy","in":"query","required":false,"description":"Strategy label to print on the card.","schema":{"type":"string"}}],"responses":{"200":{"description":"A 1200x630 PNG.","content":{"image/png":{"schema":{"type":"string","format":"binary"}}}}}}},"/api/fund-builder/og":{"get":{"operationId":"renderProviderOgImage","summary":"Render the share image for a fund service provider","description":"Renders a 1200x630 PNG Open Graph card for one provider. Used by the metadata of /fund-builder/providers/{id}.","tags":["Media"],"parameters":[{"name":"name","in":"query","required":true,"description":"Provider name to print on the card.","schema":{"type":"string"}},{"name":"category","in":"query","required":false,"description":"Category label to print on the card.","schema":{"type":"string"}},{"name":"description","in":"query","required":false,"description":"Short description to print on the card.","schema":{"type":"string"}}],"responses":{"200":{"description":"A 1200x630 PNG.","content":{"image/png":{"schema":{"type":"string","format":"binary"}}}}}}}},"components":{"schemas":{"Error":{"type":"object","description":"The error envelope returned by every endpoint at every non-2xx status.","required":["error","code","message","hint","status","docs"],"properties":{"error":{"type":"string","description":"Human-readable message. Identical to `message`; kept because the website's own forms read this key."},"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on the message text.","enum":["invalid_email","missing_required_field","invalid_json","captcha_failed","captcha_required","invalid_request","upstream_error","upstream_unavailable","method_not_allowed","unknown_endpoint","fund_not_found","provider_not_found"]},"message":{"type":"string","description":"Human-readable message, safe to show to a user."},"hint":{"type":"string","description":"What to change to make the request succeed."},"status":{"type":"integer","description":"HTTP status code, repeated in the body."},"docs":{"type":"string","format":"uri","description":"URL of this OpenAPI document."}},"examples":[{"error":"A valid email address is required.","code":"invalid_email","message":"A valid email address is required.","hint":"Send a syntactically valid address in the `email` field, e.g. \"jane@example.com\".","status":400,"docs":"https://www.fume.finance/openapi.json"}]},"SubmissionAccepted":{"type":"object","description":"Confirms the submission reached the Fume team. Nothing is returned about downstream handling.","required":["success"],"properties":{"success":{"type":"boolean","const":true,"description":"Always true; failures use the Error schema."}}},"ServiceProviderRef":{"type":"object","description":"A service provider named on a fund's record.","required":["name","role"],"properties":{"name":{"type":"string","description":"Provider name."},"role":{"type":"string","description":"What the provider does for this fund, e.g. \"Auditor\"."},"url":{"type":"string","format":"uri","description":"Canonical Fume page for the provider, when Fume lists it."}}},"Fund":{"type":"object","description":"A tokenized investment fund listed in the Fume registry.","required":["id","name","url","manager","strategy","assetClass","description","chain","tokenStandard","inception","status","jurisdiction","acceptsStablecoins","tokenizationPlatform","dataSource","lastUpdated","serviceProviders"],"properties":{"id":{"type":"string","description":"Registry slug. Stable; usable as the path parameter of getRegistryFund."},"name":{"type":"string","description":"Fund name."},"url":{"type":"string","format":"uri","description":"Canonical human-readable page for this fund."},"issuer":{"type":"string","description":"Legal issuer of the shares, when it differs from the manager."},"manager":{"type":"string","description":"Investment manager."},"strategy":{"type":"string","description":"Investment strategy."},"assetClass":{"type":"string","description":"Asset class."},"description":{"type":"string","description":"One-paragraph description of the fund."},"aumUsd":{"type":"number","description":"Assets under management in USD, when a number is known."},"aumDisplay":{"type":"string","description":"AUM as the registry displays it, e.g. \"$120M\"."},"chain":{"type":"string","description":"Chain the tokenized shares live on."},"tokenStandard":{"type":"string","description":"Token standard, e.g. \"ERC-6909\"."},"contractAddress":{"type":"string","description":"Share token contract address, when public."},"isin":{"type":"string","description":"ISIN, when the fund has one."},"inception":{"type":"string","description":"Inception date or year, as reported."},"status":{"type":"string","enum":["Open","Closed","Upcoming","Soft Close","Hard Close","Launching"],"description":"Subscription status."},"jurisdiction":{"type":"string","description":"Fund domicile."},"managementFee":{"type":"string","description":"Management fee, as reported."},"performanceFee":{"type":"string","description":"Performance fee, as reported."},"minimumInvestment":{"type":"string","description":"Minimum subscription, as reported."},"lockup":{"type":"string","description":"Lock-up terms, as reported."},"acceptsStablecoins":{"type":"boolean","description":"Whether the fund accepts stablecoin subscriptions."},"tokenizationPlatform":{"type":"string","description":"Platform that issued the tokenized shares."},"dataSource":{"type":"string","enum":["Verified onchain","Self-reported","Public filing"],"description":"How the record was sourced. Treat \"Self-reported\" as unverified."},"lastUpdated":{"type":"string","format":"date","description":"ISO date the record was last edited."},"website":{"type":"string","format":"uri","description":"Fund or manager website."},"serviceProviders":{"type":"array","items":{"$ref":"#/components/schemas/ServiceProviderRef"},"description":"Providers named on the fund's record."}}},"FundList":{"type":"object","required":["total","limit","offset","funds"],"description":"A page of registry funds.","properties":{"total":{"type":"integer","description":"Number of funds matching the filters, before paging."},"limit":{"type":"integer","description":"Page size actually applied, after clamping."},"offset":{"type":"integer","description":"Offset actually applied."},"funds":{"type":"array","items":{"$ref":"#/components/schemas/Fund"},"description":"The matching funds."}}},"Provider":{"type":"object","description":"A fund service provider in the Fume catalog.","required":["id","name","url","category","categoryId","description","tags","jurisdictions","isVerifiedPartner"],"properties":{"id":{"type":"string","description":"Catalog slug. Usable as the path parameter of getFundServiceProvider."},"name":{"type":"string","description":"Provider name."},"url":{"type":"string","format":"uri","description":"Canonical human-readable page for this provider."},"category":{"type":"string","description":"Category display name, e.g. \"Legal Counsel\"."},"categoryId":{"type":"string","enum":["legal","fund-admin","custody","broker","auditor","aifm","insurance"],"description":"Category id. Usable as the `category` filter of listFundServiceProviders."},"description":{"type":"string","description":"One-sentence description."},"longDescription":{"type":"string","description":"Full description, as shown on the provider page."},"tags":{"type":"array","items":{"type":"string"},"description":"Short labels, e.g. \"Offshore\", \"Specialist\"."},"jurisdictions":{"type":"array","items":{"type":"string"},"description":"Jurisdictions the provider covers."},"aumRange":{"type":"string","description":"Fund size range the provider typically serves."},"specialty":{"type":"string","description":"What the provider is specifically good at."},"pricing":{"type":"string","description":"Indicative pricing, as reported by the provider."},"website":{"type":"string","format":"uri","description":"Provider website."},"isVerifiedPartner":{"type":"boolean","description":"Whether Fume has a working relationship with this provider."}}},"ProviderCategory":{"type":"object","description":"One category of the provider catalog.","required":["id","name","shortName","description","providerCount"],"properties":{"id":{"type":"string","description":"Category id, used as the `category` filter."},"name":{"type":"string","description":"Category display name."},"shortName":{"type":"string","description":"Abbreviated name used in the Fund Builder canvas."},"description":{"type":"string","description":"What this kind of provider does for a fund."},"providerCount":{"type":"integer","description":"How many providers the catalog holds in this category."}}},"ProviderList":{"type":"object","required":["total","limit","offset","categories","providers"],"description":"A page of providers, plus the full category list.","properties":{"total":{"type":"integer","description":"Number of providers matching the filters, before paging."},"limit":{"type":"integer","description":"Page size actually applied, after clamping."},"offset":{"type":"integer","description":"Offset actually applied."},"categories":{"type":"array","items":{"$ref":"#/components/schemas/ProviderCategory"},"description":"Every category in the catalog, unaffected by the filters."},"providers":{"type":"array","items":{"$ref":"#/components/schemas/Provider"},"description":"The matching providers."}}},"SearchResult":{"type":"object","description":"One fumadocs search hit.","required":["id","type","url","content"],"properties":{"id":{"type":"string","description":"Identifier of the matching heading or content block."},"type":{"type":"string","enum":["page","heading","text"],"description":"Whether the hit is a page title, a heading, or body text."},"url":{"type":"string","description":"Path of the documentation page, relative to the site root."},"content":{"type":"string","description":"The matching text."},"content_with_highlights":{"type":"array","items":{"type":"object"},"description":"The same text split into highlighted and plain runs."}}}}}}