Skip to content
ACS Infra

Use API keys

Every /v1 route of the API needs an API key. GET /health and the spec at GET /openapi.json do not. Make a key in the App, then send it in the Authorization header of each request. You make keys after you sign in.

Make an API key

  1. In the App, open API Keys. Until you have a key, the App opens API Keys first after sign-in.

  2. Select New key. Until you have a key, the button is under No API keys yet.

  3. Enter a Name of up to 32 characters, such as laptop. No two of your keys can share a name, whatever the case of its letters. A revoked key's name is free again.

  4. Select Create key.

  5. In Copy your key, select Copy. The App shows the key only this once, because the API keeps only a hash of it. Every key starts with sk-acs-.

  6. Select Done. If you did not copy the key, the App asks first. It asks too before you close or reload the tab.

  7. Put the key and the API's address in shell variables. The examples in these docs read both:

    export ACS_API_KEY=sk-acs-...
    export ACS_API_BASE=https://api.v2-staging.infra.acsresearch.org/v1

If the browser does not let the App copy the key, the App shows it selected, for you to copy by hand. Set the client for long requests in Copy your key opens Set the client for long requests in a new tab.

Send the key

Send the key as a Bearer key in the Authorization header. With curl, add the header to each command:

curl "$ACS_API_BASE/models" \
  -H "Authorization: Bearer $ACS_API_KEY"
Models
{
  "object": "list",
  "data": [
    {
      "id": "llama-8b",
      "object": "model",
      "owned_by": "acs",
      "served_model_name": "meta-llama/Llama-3.1-8B",
      "gpu_shape": "1xL40S",
      "status": "live",
      "default": true,
      "capabilities": {
        "max_model_len": 131072,
        "max_logprobs": 100,
        "max_output_work_tokens": 32000,
        "max_inflight_per_key": 16,
        "max_queued_per_key": 64,
        "rate_limit_per_minute": 600,
        "logprobs": true,
        "prompt_logprobs": true,
        "prompt_logprobs_full_vocab": true,
        "full_vocab_max_prompt_tokens": 256,
        "activations": true,
        "max_steering_vectors": 8,
        "max_activation_prompt_tokens": 256,
        "n_layers": 32,
        "hidden_size": 4096,
        "chat_template": null
      }
    }
  ]
}

With the openai Python SDK, give the key as api_key. If you leave out api_key, the SDK reads the key from the environment variable OPENAI_API_KEY:

import os

from openai import OpenAI

client = OpenAI(base_url=os.environ["ACS_API_BASE"], api_key=os.environ["ACS_API_KEY"])
completion = client.completions.create(model="llama-8b", prompt="The sky is", max_tokens=2)
print(completion.usage.total_tokens)
Output
6

Fix a 401 error

The API checks the key before it reads the request body. A request without a key gets 401 with the code missing_authorization:

curl "$ACS_API_BASE/models"
Error
{
  "error": {
    "message": "You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer YOUR_KEY).",
    "type": "invalid_request_error",
    "param": null,
    "code": "missing_authorization"
  },
  "request_id": "req_9f2c4e1a7b3d4c5e8f6a0b1c2d3e4f5a"
}

The code and the message say what is wrong with the key:

codemessageWhat to do
missing_authorizationYou didn't provide an API key. ...Send the Authorization header.
invalid_api_keyIncorrect API key provided.Check the key. It starts with sk-acs-, or with acs-bm- for a key of the old platform.
key_revokedThis API key has been revoked.Make a new key.
key_disabledThis API key is paused. Resume it on API Keys in the App to use it again.Resume the key, as Manage your keys shows.
account_suspendedYour access to ACS Infra is suspended. Write to infra@acsresearch.org if you think this is a mistake.Read If your access is suspended.

When many requests from one address send a key that does not work, the API answers 429 rate_limited instead, with Retry-After.

Call the API from a browser

A page in a browser can call the API, for example with the openai JS SDK and its option dangerouslyAllowBrowser: true. The API answers every origin with CORS on /v1, /health, and /openapi.json. The page can read each answer, errors too, with the headers X-Request-Id, Retry-After, retry-after-ms, X-Should-Retry, and X-Acs-Max-Tokens-Clamped.

The API reads the API key and no cookie, so the page needs your key. Anyone who opens the page can read the key and spend your tokens. Make a key for that page alone, use the page only yourself, and revoke the key when you are done.

Manage your keys

The table on API Keys lists your active and paused keys. When you have none, the page shows No API keys yet and New key in its middle, with no table. It shows the same after you revoke your last key. The table shows each key's Name and first characters, its Status, and its tokens This month. A name that does not fit on one line is cut short. The table also shows the tokens left in the key's own Budget, and when the key was Last used and Created. A time today shows in UTC, such as 05:02 UTC, and an earlier one shows its date. On a phone, the table leaves out Budget, Last used, and Created.

The page reads the numbers again every minute while its tab is open. When a read fails, the page keeps the numbers that it read last, and shows the note Could not refresh. below the table. When you have no tokens left, the notice under the title says so, with Request more (Ask for more tokens).

Each row ends with a menu of the key's actions.

  1. To rename a key, select Rename in its menu, enter the new Name, and select Rename. The same name rule holds as for a new key.
  2. To pause a key, select Pause in its menu. Requests with the key get 401 with the paused message. Jobs and Loom Branches that the key started wait, and run when you select Resume (Paused keys and suspended access).
  3. To read what a key used, select its tokens This month, or View usage in its menu. Usage opens for that key alone (Read your usage).
  4. To stop a key for good, revoke it, as Revoke a key shows.

Make one key for each script or machine. You can then pause or revoke one key without stopping the others, and the Usage page shows the tokens of each key (Read your usage).

An admin can give a key its own Budget with a Grant for that key. That key then stops when either its own Budget or yours is empty (Your Budget). A key without its own Budget shows a dash in Budget.

You can have at most 10 keys that are not revoked (API keys in Limits). At the limit, New key is off, and a note below the table says why: You have 10 API keys, the most that a User may have. Delete one to make another. Revoke a key to make room for a new one.

Revoke a key

  1. On API Keys, open the menu at the end of the key's row, and select Revoke.
  2. Select Revoke key to confirm, or Cancel.

Requests with the key get 401 with the message This API key has been revoked. at once. Requests of Jobs and Loom Branches that the key started and that have not run yet fail, and spend no tokens. You cannot undo a revoke. The key leaves API Keys, which lists only the keys that you can use. By key on Usage still shows the tokens that the key used, under its name, with the status Revoked (Read your usage).

On this page