Skip to content

Platform / Task

Use the GraphQL API

Updated · 6 min read

Call the Origin Cloud GraphQL API with a bearer token, find operations by namespace, read resource URNs, and handle typed enums and errors.

On this page10 sections

The GraphQL API is the complete interface to Origin Cloud: the console and the origin CLI use it too. Call it directly for automation, integrations, and operations the CLI doesn’t cover.

Before you begin

Endpoint

Every request goes to one endpoint:

text
https://api.origincloud.eu/graphql

Send queries and mutations as an HTTP POST with a JSON body that holds query and, optionally, variables. The API supports GraphQL introspection, so code generators and IDE plugins can read the schema from the endpoint with a valid token.

Authenticate

Every request carries an access token as a bearer token in the Authorization header:

text
Authorization: Bearer <access-token>

A request without a token, or with an expired or invalid one, fails with the error code UNAUTHORIZED. Get a token in one of two ways:

  • As yourself: log in with the CLI, then print the token with origin id token --raw. The CLI renews it when it expires. See Use the CLI.
  • As a service account: request a token with the OAuth 2.0 client credentials grant, using the service account’s client ID and secret. See Service accounts.

Access tokens are short-lived. When a request fails with UNAUTHORIZED, get a new token and send the request again.

Send a request

  1. Write the query. This one lists the organizations you can access:

    GraphQL
    query {
      admin {
        organisations {
          orgId
          name
          status
        }
      }
    }
  2. Send it with your token:

    terminal
    curl -sS https://api.origincloud.eu/graphql \
      -H "Authorization: Bearer <access-token>" \
      -H "Content-Type: application/json" \
      -d '{"query":"{ admin { organisations { orgId name status } } }"}'
  3. Verify the response. A successful response has a data object and no errors array. Example output (illustrative):

    JSON
    {
      "data": {
        "admin": {
          "organisations": [
            { "orgId": "0a1b2c3d4e5f", "name": "Example GmbH", "status": "ACTIVE" }
          ]
        }
      }
    }

Pass values through variables rather than pasting them into the query text. That avoids quoting problems:

JSON
{
  "query": "query($org: OrgId!) { admin { organisation(orgId: $org) { name status } } }",
  "variables": { "org": "0a1b2c3d4e5f" }
}

Namespaces

Operations are grouped by service. Every query and mutation sits under one of these top-level fields:

NamespaceQueriesMutationsCovers
adminyesyesOrganizations, projects, billing accounts, quotas, usage and cost, support cases
iamyesyesMembers, invites, roles, permissions, service accounts, audit log
computeyesyesInstances, instance types, images, image families, key pairs
pvsyesyesVolumes, snapshots, storage classes
networkyesyesVPCs, subnets, network interfaces, gateways, Floating IPs, route tables, security groups, network ACLs, DNS
observabilityyesnoMetrics

For example, launching an instance is mutation { compute { launchInstance(...) { ... } } }.

Resource URNs

Every resource has a URN, a globally unique identifier returned in its urn field. Compute, storage and network operations take URNs as input, such as projectUrn, instanceUrn or subnetUrn. Organization and IAM operations take plain IDs, such as orgId and projectId.

A URN has eight colon-separated parts:

text
urn:origin:cloud:<service>:<region>:<org-id>:<project-id>:<resource-id>
PartMeaning
urn:origin:cloudA fixed prefix.
<service>The service that owns the resource: admin, iam, compute, pvs, network or observability.
<region>The region the resource lives in, such as eu-central1. Empty for resources that aren’t bound to a region.
<org-id> and <project-id>The organization and project that own the resource. Empty where they don’t apply.
<resource-id>The resource’s own ID within the service.

Examples:

ResourceURN
Organizationurn:origin:cloud:admin::::0a1b2c3d4e5f
Projecturn:origin:cloud:admin::0a1b2c3d4e5f::demo-48291037561
Instanceurn:origin:cloud:compute:eu-central1:0a1b2c3d4e5f:demo-48291037561:i-79PVin5MmNc
Built-in roleurn:origin:cloud:iam::::tc/role/roles/viewer

Copy a URN from the urn field of a response rather than assembling it yourself. The one URN you often need without having it at hand is a project’s: it’s urn:origin:cloud:admin::<org-id>::<project-id>. The API returns it as the project’s urn field, and origin admin create-project prints it, but origin admin get-project and list-projects don’t.

Typed enums

Statuses and other closed sets of values are GraphQL enums, not free text. Examples are an organization’s status (PENDING_REVIEW, ACTIVE, REJECTED), a billing account’s paymentMethodStatus, and an instance’s status.

  • Generate your client types from the schema. A typed client lists every value the schema defines, and fails to compile when a value is added that your code doesn’t handle.
  • Compare against the enum, not against strings copied from a response.
  • Handle a value your code doesn’t recognize explicitly, for example by surfacing it, rather than mapping it to a default.

Lists and pages

Most list queries return a plain list. A few queries that can return many entries, such as the audit log and support cases, return a page instead: the entries plus total, hasMore, offset and limit. Read the next page by adding limit to offset, while hasMore is true. For page size limits, see Limits.

Errors

A failed operation returns an errors array. Each error has a message and, in extensions, a stable code, a retryable flag and a correlationId:

JSON
{
  "errors": [{
    "message": "invalid input on field sizeInGib: must be at least 1",
    "extensions": {
      "code": "BAD_REQUEST",
      "retryable": false,
      "correlationId": "4bf92f3577b34da6a3ce929d0e0e4736"
    }
  }]
}

Branch on code, never on the message text: codes are stable, messages can change. For every code and what to do about it, see Error codes.