The BEEM API is a single GraphQL endpoint. Here's how to send requests, read this reference, and paginate through results.
There is no /v1/datasets or /users/me — those concepts exist as fields inside the GraphQL schema, not as separate REST paths. Every operation, read or write, goes through one URL.
The endpoint
POST https://api.beemdata.com/graphql
Request shape
Every request is a POST with Content-Type: application/json and a body of three fields:
{
"query": "query GetWorkspace($id: ID!) { getWorkspace(id: $id) { id name } }",
"operationName": "GetWorkspace",
"variables": { "id": "..." }
}| Field | Required | Description |
|---|---|---|
query | yes | The GraphQL operation document. May contain multiple operations — operationName selects which to run. |
operationName | recommended | Name of the operation in query to execute. |
variables | depends | Map of variable name → value, matching the $variable placeholders in query. |
A complete authenticated example:
TOKEN="<your access token>"
curl -X POST https://api.beemdata.com/graphql \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"query": "query { listWorkspaces { items { id name } } }"
}'Reading this reference
This reference documents each GraphQL field — both queries and mutations — as its own page. Browse by resource (Datasets, Sources, Connections, etc.) under Queries & Mutations, or look up a type (Dataset, Workspace, Connection) under Types.
A few conventions:
- Sidebar labels are raw GraphQL field names (
getDataset,listDatasetsByWorkspace). The page header gives you the human-readable name. - Each operation page comes with a pre-filled query string. Copy-paste it as-is — you only need to fill in
variables. - Type pages cross-link. Clicking a field type on a Type page jumps to that type's own page, so you can navigate the schema as a graph.
About the URLs you'll see
In Try It and the code samples, you'll see paths like POST /graphql/query/getDataset or POST /graphql/mutation/createDataset. These exist purely so this reference can render one page per operation — readme.io requires a unique URL per documented endpoint.
On the wire, every request goes to POST /graphql. The operation discriminator is in the request body (the query and operationName fields), not in the URL. Our edge layer rewrites /graphql/{kind}/{name} → /graphql before forwarding to the API, so the URLs as shown will work regardless.
Sub-selections
Unlike REST, GraphQL requires you to specify exactly which fields you want back. The pre-filled queries in this reference include every scalar field of the return type — useful for exploration, but oversized for production. Trim the selection set to what you actually need:
# Pre-filled query — fetches every field
query GetDataset($id: ID!) {
getDataset(id: $id) {
id
name
description
createdAt
updatedAt
workspace { id name organization { id name } }
owner { id email }
# ... 40 more fields
}
}
# Trimmed for your actual use case
query GetDataset($id: ID!) {
getDataset(id: $id) {
id
name
workspace { id name }
}
}Smaller selection sets mean faster responses and less data over the wire — worth doing for high-traffic operations.
Pagination
Queries that return lists support cursor-based pagination via two arguments:
| Argument | Description |
|---|---|
limit | Maximum number of items to return per page (default 25, max 100). |
nextToken | Pagination cursor returned by the previous request. Pass back in to get the next page. |
The response is wrapped in a Connection object:
query ListDatasets($workspaceId: ID!, $nextToken: String) {
listDatasetsByWorkspace(workspaceId: $workspaceId, limit: 50, nextToken: $nextToken) {
items {
id
name
}
nextToken # null when there are no more pages
}
}To fetch all results, loop until nextToken comes back null.
Versioning
The API is unversioned. Backwards-incompatible changes — removing a field, narrowing a type, making an optional argument required — are announced with at least 90 days' notice via the changelog. Additive changes (new fields, new operations, new optional arguments) ship without notice and don't require any client update.
If you depend on a field that isn't present in the response, the field was probably added after your client was built — refetch the schema or check the changelog.
