Cube Logo0.33.23


REST API enables Cube to deliver data over the HTTP protocol to certain kinds of data applications, including but not limited to the following ones:

Often, the REST API is used to enable embedded analytics and real-time analytics use cases.

If you've chosen GraphQL as a query language for your front-end application, consider using the GraphQL API that Cube also provides.

By default, all REST API endpoints are prefixed with a base path of /cubejs-api, e.g., the /v1/load endpoint will be available at /cubejs-api/v1/load.

Exception: /livez and /readyz endpoints are not prefixed with a base path.

You can set a desired base path using the basePath configuration option.

Each REST API endpoint belongs to an API scope, e.g., the /v1/load endpoint belongs to the data scope. API scopes allow to secure access to API endpoints by making them accessible to specific users only or disallowing access for everyone. By default, API endpoints in all scopes, except for jobs, are accessible for everyone.

API scopeREST API endpointsAccessible by default?
meta/v1/meta✅ Yes
data/v1/load, /v1/sql✅ Yes
graphql/graphql✅ Yes
❌ No

Exception: /livez and /readyz endpoints don't belong to any scope. Access to these endpoints can't be controlled using API scopes.

You can set accessible API scopes for all requests using the CUBEJS_DEFAULT_API_SCOPES environment variable. For example, to disallow access to the GraphQL API for everyone, set CUBEJS_DEFAULT_API_SCOPES to meta,data.

You can also select accessible API scopes for each request using the contextToApiScopes configuration option, based on the provided security context. For example, to restrict access to the /v1/meta endpoint to service accounts only, you can set CUBEJS_DEFAULT_API_SCOPES to data,graphql and use the following configuration in the cube.js file, assuming that service accounts have service: true in their security context:

module.exports = {
  contextToApiScopes: (securityContext, defaultScopes) => {
    if (securityContext.service) {
      return ['meta', ...defaultScopes];
    return defaultScopes;

REST API supports Cross-Origin Resource Sharing (CORS). By default, requests from any origin (*) are allowed.

You can configure CORS using the http.cors configuration option. For example, to allow requests from a specific domain only, use the following configuration in the cube.js file:

module.exports = {
  http: {
    cors: {
      origin: ""

Cube uses API tokens to authorize requests and also for passing additional security context, which can be used in the queryRewrite property in your cube.js configuration file.

The API Token is passed via the Authorization Header. The token itself is a JSON Web Token, the Security section describes how to generate it.

In the development environment the token is not required for authorization, but you can still use it to pass a security context.

curl -H "Authorization: EXAMPLE-API-TOKEN"

If the request takes too long to be processed, Cube Backend responds with { "error": "Continue wait" } and 200 status code. This is how the long polling mechanism in Cube is implemented. Clients should continuously retry the same query in a loop until they get a successful result. Subsequent calls to the Cube endpoints are idempotent and don't lead to scheduling new database queries if not required by the refresh_key. Also, receiving Continue wait doesn't mean the database query has been canceled, and it's actually still being processed by the Cube. Database queries that weren't started and are no longer waited by the client's long polling loop will be marked as orphaned and removed from the querying queue.

Possible reasons of Continue wait:

  • The query requested is heavy, and it takes some time for the database to process it. Clients should wait for its completion, continuously sending the same REST API request. continueWaitTimeout can be adjusted in order to change the time Cube waits before returning Continue wait message.
  • There are many queries requested and Cube backend queues them to save database from overloading.

Cube REST API has basic errors and HTTP Error codes for all requests.

StatusError responseDescription
400Error messageGeneral error. It may be a database error, timeout, or other issue. Check error message for details.
403Authorization header isn't setYou didn't provide an auth token. Provide a valid API Token or disable authorization.
403Invalid tokenThe auth token provided is not valid. It may be expired or have invalid signature.
500Error messageCube internal server error. Check error message for details.

For monitoring tools such as Cube Cloud proper request span annotation should be provided in x-request-id header of a request. Each request id should consist of two parts: spanId and requestSequenceId which define x-request-id as whole: ${spanId}-span-${requestSequenceId}. Values of x-request-id header should be unique for each separate request. spanId should define user interaction span such us Continue wait retry cycle and it's value shouldn't change during one single interaction.

Cube supports paginated requests for the /v1/load endpoint by including limit and offset parameters in the query. For example, the following query will retrieve rows 101-200 from the Orders cube:

  "dimensions": ["Orders.status"],
  "measures": ["Orders.count"],
  "timeDimensions": [
      "dimension": "Orders.createdAt",
      "dateRange": "last year",
      "granularity": "day"
  "limit": 100,
  "offset": 100

Did you find this page useful?