API
Call the OpsLyft GraphQL API with an access key to read cost, anomalies, inventory, budgets, and tickets.
The OpsLyft API gives scripts and integrations the same data you see in the app: cost broken down any way you like, anomalies, your live Atlas inventory, budgets, and tickets. Use it to feed a data warehouse, post a weekly cost report to chat, or build your own dashboard.
It's a GraphQL API: you send one POST request with a query that names exactly the fields you want, and get back JSON in the same shape.
Endpoint
POST https://v2.opslyft.com/api/apiYes, api twice: the first is OpsLyft's API path, the second is the GraphQL endpoint itself.
Authenticate
Create an access key, then send it on every request:
Authorization: Bearer olt_1a2b3c4d_…
Content-Type: application/jsonThe key decides what you can read. A key scoped to one AWS account only ever returns cost for that account.
Your first request
Ask the API what your key can do. This works with any key.
curl https://v2.opslyft.com/api/api \
-H "Authorization: Bearer $OPSLYFT_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ myAccess { customerId modules keys } }"}'Response:
{
"data": {
"myAccess": {
"customerId": "a1b2c3d4e5",
"modules": ["atlas", "budget", "cost", "monitor", "ticket"],
"keys": ["atlas.view", "budget.view", "cost.view", "monitor.view", "ticket.view"]
}
}
}keys lists the permissions the key holds. Each operation in the API reference says which one it needs.
Send variables
Put values in variables rather than pasting them into the query string. It avoids escaping problems.
{
"query": "query Cost($req: CostQueryInput!) { costQuery(request: $req) { rows total } }",
"variables": {
"req": {
"providers": ["aws"],
"dateRange": { "from": "2026-09-01", "to": "2026-10-01" },
"groupBy": ["service_name"]
}
}
}Conventions
- Dates are
YYYY-MM-DD. In cost queries the end of a range is exclusive: September is{ "from": "2026-09-01", "to": "2026-10-01" }. - Timestamps are ISO 8601 in UTC.
- Money is a number in the currency the response names (
currency), usually your organisation's display currency. - Providers are lowercase keys:
aws,azure,gcp,oracle,snowflake,databricks,openai. - Bill delay: cost data usually runs a day behind. See Data freshness.
- Pagination depends on the operation. Each one in the reference says how it pages.
Errors
Errors come back in the standard GraphQL errors array, each with a code:
{
"errors": [
{
"message": "Missing permission cost.view",
"extensions": { "code": "MISSING_PERMISSION", "http": 403, "key": "cost.view" }
}
],
"data": null
}Always check for errors before reading data. See Errors and limits for every code and what to do about it.
What the API covers
| Area | Read | Write |
|---|---|---|
| Your key's access | Yes | — |
| Cost | Yes | — |
| Anomalies | Yes | Not yet with access keys |
| Atlas inventory and change history | Yes | — |
| Budgets | Yes | Not yet with access keys |
| Tickets | Yes | Not yet with access keys |
| Canvases, datasets, saved views, Dimension Studio | Not yet with access keys | Not yet with access keys |
Operations not listed in the API reference are internal to the OpsLyft app and can change without notice. Don't build on them.
No schema introspection
Introspection is turned off in production, so GraphQL tools can't download the schema. The API reference has the types you need.
Tips
- Request only the fields you need. Smaller queries return faster.
- Set a long timeout. Large cost queries can take up to two minutes. OpsLyft stops a query that runs longer.
- Cache results. Cost for past days rarely changes, so a nightly pull is usually enough.
- Use one key per integration, with the smallest role that works. Viewer is enough for every operation in the reference.
Related
- API reference
- Access keys
- Errors and limits
- MCP, if you want an AI client to ask the questions for you