your key and the write permission
- create a key in the API dashboard and send it as
Authorization: Bearer <your-api-key>on every request, as for any other call. only an API key works here: a browser session does not. every route acts on the account that owns the key; there is no member id to pass. - writes are on by default, and one permission covers Claude and your own code. in the API dashboard, under let Claude or your code write to your account, this API key covers every client that uses the key, whether that is Claude over MCP or your script over REST. turning it off keeps every read working, and
GET /v1/settingsreportswrites_enabledfor the key you sent. - the reads work on any API-enabled plan with writes off; the writes need the permission.
endpoints
each route has the same name as the MCP tool it mirrors. a refusal message that names an operation (for example “list_report_catalog with surface screener lists them”) refers to this table.
the full request and response shapes are in the API reference groups settings and custom reports in the sidebar.
try it
how writes behave
- the app shows the change after reload. an Edgeful tab that was open before your write keeps its old copy of your bookmarks and watchlists and overwrites the change the next time it saves. a scheduled integration cannot reload that tab, so expect bookmark and watchlist additions made while you are in the app to be reverted by the tab’s next save until you reload it.
- writes are idempotent change sets. a
POSTcarries what to add and remove, or the fields to change, never a whole list to replace. adding a bookmark or ticker you already have, or removing one you do not, succeeds withstatusunchanged; creating a session or template equal to one you already saved converges on it. a write answers200withstatuscreated,updated,unchangedordeleted, and a repeated delete isunchanged, not404, so resending a request after a timeout is always safe. - every result carries what undo needs. a defaults write returns the
previousdefaults, a customization write each key’spreviousvalues (null when the key had none, so a reset undoes it) and a template update theprevioustemplate, and sending those back undoes the change. bookmark and watchlist writes return the previous and current lists and whatchanged, so removing what was added and adding what was removed undoes them. deletes return the removed object so it can be saved again under a new id. a custom-session save returns the saved session and the full list. - send writes one at a time. writes to one account serialize on your profile, so parallel requests only wait for each other.
- Edgeful validates before it saves. report slugs and sub-reports come from the report catalog, tickers must be known on the market you name, a default session must be a standard session the report allows on that market, and a custom session needs
HH:MMstart and end times that differ and an IANA timezone. an invalid request is refused with400and adetailthat lists the allowed values. - defaults are reconciled like the account form. the report constrains the market, a market change resets the ticker to that market’s default, and the session is re-resolved when the report no longer allows it.
- report customizations land where the page reads them, in slots (
value,value2, …) under the setting key, checked the way the page’s customization modal checks them; each record carries the key’s previous and resulting values and, per page, the query a report endpoint needs to apply them. the MCP settings page spells out the slot, template and What’s in Play rules in full; the REST routes apply exactly the same ones. - templates are applied in Edgeful. saving a template does not change any report page. it appears in its picker after a reload, or the app’s five-minute template refetch, and you apply it from there.
- every write is logged with the operation, your member id and the key that made it. settings writes cost no AI credits.
errors and retries
two
400 messages mean retry rather than fix: “Ticker validation is temporarily unavailable; try again shortly.” and a customization that “was saved from Edgeful at the same time”. everything else under 400 needs a different request. honour Retry-After when it is present and back off otherwise; a tight retry loop on 429 burns the hourly budget, because refused attempts count.
budgets and limits
- settings writes share one budget per account of 60 per minute and 600 per hour across Claude’s MCP connections and every API key, so a script writing in a loop can leave Claude refused for the rest of the window, and the reverse. one request counts once however many items it carries, refused attempts count too, and each list is capped at 100 items.
- custom-report runs share a budget of 60 per minute and 600 per hour with Claude’s runs, and every run request counts, one that returns an existing result included. saves and deletes share a budget of 10 per minute and 100 per hour with Claude’s other custom-report writes.
- a run that needs a fresh computation also uses your run allowance of 200 per hour, shared with builds in Edgeful, and fresh computations run one at a time per account: starting another while one computes is a
429withrun_limit_concurrentandretry_after_seconds, so start a dashboard’s runs one after another. a run already made for the same inputs and completed data uses neither. - every call also counts against the key’s request limits from authentication: 120 per 60 seconds, 30 per 10 seconds and 1,500 per hour.
- settings and custom-report calls do not appear in the API dashboard’s usage numbers, which count report calls.
- reads are never budgeted.
custom reports over REST
building and revising a report stay with Claude over MCP and in Edgeful AI. everything you do with a saved report works here.- list and read.
GET /v1/custom-reportsreturns your saved reports withtotal,has_moreandnext_offset; passnext_offsetasoffsetfor the next page, andlimitup to 100.GET /v1/custom-reports/{definition_id}/latest-resultreturns the latest successful stored result with theeffective_controls,data_throughandcomputed_atit actually used, orstatusno_resultwhen no saved run has completed yet. neither starts a run. - every row. a result carries every row the run stored, with
total_rows; Claude’s tools page the same rows a hundred at a time. a run whose result would exceed about 512 KB stores nothing and fails with “result too large - narrow the window.” - run.
POST /v1/custom-reports/{definition_id}/runsruns the saved code on its saved inputs, or oncontrolsthat change the ticker, session or dates; the market and granularity stay locked, and runs use no AI credits. a run already made for the same inputs and completed data comes back at once with200. otherwise the run starts and answers202withstatusrunning, itsrun_idandpoll_after_seconds: read it withGET /v1/custom-reports/{definition_id}/runs/{run_id}untilstatusis no longerrunning. a failed run withretryabletrue is retried by sending itsrun_idasretry_of_run_idwith the same controls. - save and delete.
POST /v1/custom-reportssaves a reviewed draft from a build in Claude, named by itsconversation_idandmessage_id, under thenameyou give it.DELETE /v1/custom-reports/{definition_id}deletes a saved report and its stored runs; deleting it again is a404.
the playground sends real requests
the try it button on a write route changes your account, and on a delete route removes the template, session or custom report you name. settings results carry what undo needs, but a deleted custom report and its stored runs cannot be restored here. it is not a sandbox.versioning
routes under/v1 only grow: new routes, fields and codes may appear without notice, and a documented route, field, status or code is not removed or renamed under /v1.