Skip to main content
API keys authenticate machine-to-machine integrations. These include scripts, automations, ETL jobs, MES bridges, IoT devices, and other systems that call ION without a person signing in. You create, manage, and delete them through the API or the UI. For user-facing applications where ION enforces a specific user’s permissions, use OAuth 2.0 instead.

How API keys behave

  • Each API key is specific to the environment it was generated in. A key created in production will not work in sandbox.
  • A key holds the same permissions the creating user had at the moment it was generated. Later changes to that user’s permissions do not affect the key.
  • Generating a new key does not invalidate previously generated keys. They keep working until disabled.
  • Any automation using a key acts on behalf of the user who created it.
  • A key is automatically disabled when its user is deactivated.
You need the APIKeyObject family of permissions to work with API keys. See the permissions reference for details.
For automations and integrations, back the key with a service account rather than an individual’s user.

Create a key

An org admin provisions API keys. Each key is bound to a user identity in your organization. Audit logs then reflect which integration made each call.
mutation CreateAPIKey {
  createApiKey {
    apikey {
      clientId
      clientSecret
    }
  }
}
The clientSecret is shown once. Capture it immediately and store it in a secrets manager such as AWS Secrets Manager, HashiCorp Vault, 1Password, or your CI/CD’s encrypted secrets store. ION cannot retrieve a secret after creation.

Get an access token

A key’s clientId and clientSecret exchange for a short-lived access token through the client-credentials grant. ION then accepts that token on the Authorization header. Most integrations use a small client library that handles the exchange and caching for you. See the Build an API client for a runnable example. To exchange the credentials directly, POST a client_credentials grant to the auth server for your environment:
curl -X POST \
  --data-urlencode "grant_type=client_credentials" \
  -d "client_id=CLIENT_ID" \
  -d "client_secret=CLIENT_SECRET" \
  https://<AUTH_SERVER>/realms/api-keys/protocol/openid-connect/token
The auth server and API endpoint differ per environment:
App URIAuth ServerAPI Endpoint
staging.firstresonance.io / sandbox.firstresonance.iostaging-auth.buildwithion.comhttps://staging-api.buildwithion.com
app.firstresonance.ioauth.buildwithion.comhttps://api.buildwithion.com
staging.ion-gov.com / sandbox.ion-gov.comauth-staging-gov.buildwithion.comhttps://api-staging-gov.buildwithion.com
app.ion-gov.comauth-production-gov.buildwithion.comhttps://api-production-gov.buildwithion.com
staging.ion-aus.comauth-staging-aus.buildwithion.comhttps://api-staging-aus.buildwithion.com
app.ion-aus.comauth-production-aus.buildwithion.comhttps://api-production-aus.buildwithion.com
Append /graphql to the API endpoint for query requests, for example https://staging-api.buildwithion.com/graphql. For more runnable scripts, see the ion-examples repository.

List keys

List your organization’s API keys:
query APIKeys {
  apiKeys {
    edges {
      node {
        clientId
        clientSecret
        id
        _etag
      }
    }
  }
}

Enable, disable, or regenerate a secret

Update a key with this mutation:
mutation UpdateAPIKey($input: APIKeyInput!) {
  updateApiKey(input: $input) {
    apikey {
      clientId
      clientSecret
      enabled
    }
  }
}
Set the variables:
{
  "input": {
    "clientId": "<your-client-id>",
    "_etag": "<your-api-keys-_etag>",
    "enabled": true,
    "regenerateSecret": false
  }
}
Set enabled to false to disable a key. Set regenerateSecret to true to rotate its secret. Disabling takes effect immediately. The next request using that key returns 401 Unauthorized.

Rotate a key

Rotate an API key when:
  • The key might have been exposed, such as being committed to a public repo, leaked in logs, or held by an employee who has left.
  • Your org’s security policy requires periodic rotation.
  • An integration is being decommissioned.
Rotate with zero downtime:
  1. Provision a new key alongside the existing one.
  2. Deploy the new key to the integration and verify traffic is succeeding with it.
  3. Delete the old key.
The old and new keys are both valid during the cutover window. Consumers don’t see auth failures.

Delete a key

Delete a key with this mutation:
mutation DeleteAPIKey($input: APIKeyInput!) {
  deleteApiKey(input: $input) {
    apikey {
      clientId
    }
  }
}
Set the variables:
{
  "input": {
    "clientId": "<your-client-id>",
    "_etag": "<your-api-keys-_etag>"
  }
}
Deletion is immediate. The next request using that key returns 401 Unauthorized.

Service accounts

Service accounts decouple API keys from individual users who might get deactivated. They also make clear that the actions in ION come from a shared service rather than from one person. A service account is an email your company creates and maintains outside of any employee’s email. Multiple people can access it as needed.