API keys

Turn on the API, make a key, pick its scopes and expiry, store it, roll it with a 24-hour overlap, revoke it, and know what stops it and what to do if one leaks.

A key lets your code read through the Developer API as you, in one organization. This page covers a key's whole life. You manage your keys at dev.usehalo.net/keys, signed in with your Halo account: a key can't make, roll or revoke keys.

Turn it on

The Developer API is off in every organization until one of its own Owners or Admins turns it on. Halo staff can't do it for you.

  1. In Halo Data, go to Settings, API access.

  2. Turn on Let members use the Developer API. It saves at once, and the audit log records it.

Turning it on makes no keys. Each member whose role has api.use then makes their own. If you aren't an Owner or Admin, your keys page says the API is off and gives you a link to send one of them. The playground's sample data works either way.

Who may make one

  • Your role has api.use. Owner, Admin, Builder and Analyst do by default, and Viewer and External guest don't.

  • The Developer API is on for the organization. It's off until an Owner or Admin turns it on.

  • Your session finished two-factor authentication, if you've set it up.

  • You aren't Halo staff viewing as someone.

  • You have fewer than 25 live keys in the organization. Playground keys don't count.

  • You've made or rolled fewer than 30 keys in the last hour.

  • You signed in within the last 15 minutes. If you didn't, Sign in again takes you through it and back here. Playground keys don't need this.

Make a key

Choose New key. Give it a Name that says what it's for, up to 200 characters, such as "Nightly sync". Then choose what It may do and when it Ends after, and choose Make key.

The key is shown once, and Test it checks that it works. Halo stores only a SHA-256 hash, and lists show only a hint: the prefix and first six characters.

Pick scopes

Give a key the fewest it needs. Scopes only narrow what your role allows.

It mayScopeAllows
See datasets and their fieldsdatasets.readNames, descriptions and fields of the datasets you can see
Query datadata.queryAggregate and read rows, and read a chart's rows. Your role must be able to export
See charts, reports, websites and the directorycontent.readList and read the charts and reports you can see, and websites, listings and businesses where you have a role in those products

A job that copies rows from a dataset you already know needs only Query data.

Pick an expiry

Every key ends. You can pick 30 days, 90 days or a year, with 90 as the default. Pick the shortest you can keep rolling. You'll hear seven days before it ends.

Store it

Read it from the environment or a secret manager, and pass it in the Authorization header.

import os

headers = {"Authorization": f"Bearer {os.environ['HALO_API_KEY']}"}
  • Never commit it, or put it in a URL, browser code, a mobile app, a log or a prompt.

  • Use one key per integration, so you can roll or revoke one without touching the others.

  • Keys start with hak_, so a pre-commit hook or secret scanner can look for them.

Roll a key

Rolling replaces a key without downtime. Only the person who made a key can roll it, since rolling shows a secret.

  1. Choose the key's roll button at the keys page, then Roll key. You get a new key, with the same name and scopes, that lasts as long as the old one did, counted from now.

  2. Put the new secret where your code reads it, and deploy.

  3. Check it with GET /v1/developer/whoami: key.id and key.expiresAt are the new key's.

Until it ends, the old key is marked Replaced in your list. It can be revoked, but not rolled again: 409 key_replaced.

The old key keeps working for 24 more hours, and never longer than it had left. A key that has already expired or been revoked can't be rolled, so make a new one.

Revoke a key

Revoking stops a key at once, and its record stays. You can revoke your own, and anyone with members.manage can revoke anyone's. It can't be undone.

What stops a key

Some changes revoke a key for good, in the same database transaction, whatever made the change. Undoing the change doesn't bring the key back. Others stop it only while they last.

What changedWhich keysWhat your code seesAfterwards
The key reached its expiry, or was revokedThat key401 invalid_api_keyMake or roll another
The session that made a playground key ended, such as by signing outThat playground key401 invalid_api_keyMake another
The person's password changedAll theirs, in every organization401 invalid_api_keyMake another
Their two-factor was set up, changed or removedAll theirs, in every organization401 invalid_api_keyMake another
Their account was deletedAll theirs, in every organization401 invalid_api_keyGone
Their membership was suspended or removedAll theirs in that organization401 invalid_api_keyMake another once they're back
Their role no longer has api.useAll theirs in that organization403 forbiddenWorks again with a role that has it
The API was turned offEveryone's in that organization403 api_disabledWorks again when it's back on
The organization was suspendedEveryone's in that organization403 org_suspendedWorks again when it's restored
The organization began requiring two-factor, and they haven't set it upTheirs in that organization403 mfa_enrollment_requiredSetting it up changes their two-factor, which revokes the key, so make another
The organization stopped allowing how they signed in when they made the keyThose keys403 sign_in_method_requiredWorks again if it's allowed again

Because a key ends with its person, watch for 401 in production and alert someone. Keys owned by the organization are planned.

If a key leaks

  1. Stop it. Revoke it at once if you can take the outage. Otherwise roll it, deploy the new secret, and revoke the old key right away rather than waiting out the 24 hours. Rolling alone leaves the leaked key working for a day.

  2. See what it did. Your keys list has each key's last use and number of requests, and Recent requests has your latest 20, with their operation, result, rows and request id. Halo keeps the log for 90 days. An Owner or Admin can also see the address a key was last used from.

  3. If you can't reach it, ask an Owner or Admin. They can revoke anyone's key.

  4. Find the source. Remove it from wherever it leaked, and treat old copies, such as git history, as public.

A leaked key reads what its person can read, within its scopes, and can't change anything. 400 key_in_query means a key was in a URL: the request was refused, but something may have logged the URL, so roll that key.

Notices

Halo tells the key's person, in Halo and by email by default. Each notice links to the keys page.

WhenThe notice says
A key is madeAn API key was made on your account
A key is rolledAn API key was replaced on your account
A key ends within seven days, once per keyYour API key ends soon
An Owner or Admin revokes itAn admin revoked your API key
Halo revokes itHalo revoked your API key

If you get one you didn't expect, revoke the key. Playground keys send no notices. The changes in What stops a key don't send a key notice either.

What Owners and Admins can see and do

Owners and Admins have a page for this in Halo Data, under Settings, API access.

On that pagePermissionWhat it does
Let members use the Developer APIorg.manageIt starts off. On lets members make keys. Off stops every key on its next request, and they stay listed for when it's back on
Every member's keysmembers.manageShows each key's name, hint, member, scopes, last use with its address, and end. Revoking one stops it at once and tells its person
Recent requestsmembers.manageThe latest 50 requests from any key

Members see only their own keys and requests. No one can read a secret, and an Admin can't roll someone else's key, since that would show them one.

The audit log records api_key.created, api_key.rolled, api_key.revoked and api.settings_updated, never the secret. Reads appear there too: see The security model.