SDKs
Call the Costfluent Public API from Go, Python or TypeScript with a client that pages, retries safely and keeps money exact, under a token scoped to your script.
Costfluent publishes three clients for the Public API, open source under the Apache 2.0 licence: costfluent-go for Go, costfluent-python for Python and costfluent-typescript for TypeScript. The Python and TypeScript clients are generated from the API's OpenAPI document and cover every operation; the Go client is written by hand, with typed methods that its tests hold to the same document. All three send your API token as a bearer token, follow list pages, retry what is safe to retry and hand amounts of money over as exact decimal strings.
Before you start
Included in the Pro, Business and Custom plans. Compare plans
- Creating the token needs the Owner, Integration Owner or Editor organization role; see Public API authentication.
- Go 1.24 or later, Python 3.11 or later, or Node.js 20 or later. The TypeScript client runs wherever
fetchdoes, which includes Deno, Bun and edge runtimes.
Create a token
- Open Settings, then API tokens, and select Create API token.
- Enter a Name that says which script uses the token, such as
Nightly budget export. - Under Access, choose the workspace the script works in, so the token reaches nothing else. Keep Whole organization only when the script reads several workspaces.
- Under Start from, choose Read only, then select the write capabilities the script needs and clear every capability it does not call. The examples on this page need View workspaces and, to create a folder, Create folders.
- Choose an Expiration, such as 90 days, and select Create API token.
- Copy the token from Your API token. It is shown only once.
The clients do not read the token from anywhere themselves: your code passes it in. Keep it in an environment variable or a secret store, never in source code, and run the TypeScript client on a server: a token in a browser bundle is a token anyone can read.
Install a client
The Go package is imported as github.com/costfluent/costfluent-go/costfluent.
Make a first call
Each example reads the token from COSTFLUENT_API_TOKEN and lists every workspace the token can see.
In Python, each operation is a module under costfluent.api, with sync and asyncio functions and their _detailed twins that also return the status and headers; the models are under costfluent.models. In TypeScript, an operation is addressed by its method and path, with the path, query and body typed from the API. In Go, each operation the client covers is a method on it.
Read every page
A list answers one page at a time (Public API pagination). Each client reads them all for you:
- Go: a paginated resource has a
ListAllmethod, such asListAllWorkspaces(ctx, pageSize)orListAllBudgets(ctx, workspaceID, pageSize), which requests page after page untillinks.nextis empty. The plain list method reads one page withPageOptionsand returns itsLinks. - Python:
paginatetakes a generatedsyncfunction and its arguments and yields every item;apaginatedoes the same for anasynciofunction. - TypeScript:
paginatetakes a function that makes the typed call and passes on thequerySerializerit is handed, and yields every item.
Python and TypeScript follow links.next, and always request the next page from the client's own base URL, so the token goes nowhere else.
Read cost data from one state
A sync that lands while you page through cost data can make a later page repeat a row or skip one (Notice a sync between pages). Read the first page, then send its meta.dataVersion with the rest: DataVersion on CostDataQuery in Go, data_version in Python, dataVersion in TypeScript. Python's and TypeScript's paginate keep it from page to page, because links.next carries it.
A page whose data a sync changed since the first fails with the API's 409: costfluent.IsConflict(err) in Go, a CostfluentError whose code is conflict in Python and TypeScript. Read the window again from page 1.
Money stays exact
An amount of money arrives as the exact decimal string the API writes, such as "1250.50000000", never as a binary float (Public API data formats).
- Go: an amount is a
costfluent.Decimal.EqualandCmpcompare two amounts by value, whatever their scale,Ratreturns the exact value, andcostfluent.ParseDecimalchecks an amount before you send it. - Python: an amount is a
str. Convert it withdecimal.Decimal(amount)to calculate with it. - TypeScript: an amount is a
string. Keep it as one, or use a decimal library to calculate with it.
Retries
All three clients retry on their own, by the same rules:
- A
429is retried for every method, after theRetry-AfterorRateLimit-Resetthe API sends (Public API rate limits). - A
5xx, a connection error, or a404that is not the API's own error body but a proxy's, is retried forGET,HEAD,PUT,DELETEand creates. OtherPOSTrequests, which start work such as a sync, are not retried, and neither is a request withIf-Match: resending one the API had already applied could run it twice or fail on its own change. - Retries back off exponentially from one second, with jitter, at most three times. Python's
max_retriesand TypeScript'smaxRetrieschange the count. - A wait over 60 seconds means the token's request budget is spent: the call fails at once with the
429instead of waiting it out. - A request that times out is not retried. The timeout is 30 seconds unless you set another:
WithTimeoutin Go,timeoutin Python,timeoutMsin TypeScript.
Creates run once
Every create sends a fresh Idempotency-Key and resends the same key on each of its retries, so the API answers a retried create with its first response instead of creating a second object (Public API data formats). Python and TypeScript let you choose the key, for example so that a job run again soon after a failure gets the folder the first run created; the Go client always generates its own.
A key the API already saw with another request is refused with idempotency_key_reused: costfluent.IsIdempotencyKeyReused(err) in Go, is_idempotency_key_reused in Python and isIdempotencyKeyReused in TypeScript.
Versions and the contract
The three clients share one version number, 1.MINOR.PATCH; Go modules write it with a leading v. The major is the API's path version, v1. The minor rises with each release that carries a newer API contract, and the patch is a fix to the client alone.
Each client also carries the SHA-256 of the Public API document it was built from: costfluent.ContractSHA256 in Go, costfluent.CONTRACT_SHA256 in Python and CONTRACT_SHA256, exported by @costfluent/sdk, in TypeScript. Two clients with the same hash were built from the same contract. What version 1 of the API may and may not change is Public API versioning.
How it behaves
- Once its retries are spent, a call that the API refuses fails with the API's error: a
*costfluent.APIErrorin Go, aCostfluentErrorin Python and TypeScript, each with the status and the API'scode(Public API errors). - A proxy's
404while the API restarts never reads as a missing object:costfluent.IsNotFound(err)in Go,is_not_foundin Python andisNotFoundin TypeScript are true only for the API's own answer. - In Go, a workspace-scoped method takes a workspace ID, or falls back to the client's
WithWorkspacedefault; a call with neither fails before it is sent. A workspace token reads its own workspace only, and the API refuses any other. - Every call counts against the token's request limit.
- The clients call
https://api.costfluent.comunless you set another base URL.