Skip to main content

Introduction

The Admin API lets you manage regular organization API keys, inspect organization billing data, and access container-related APIs with an admin API key. Admin API keys are for organizations, not personal accounts.

Common use cases

  • Automating key management: Create, rotate, or delete API keys programmatically, and set expiration dates or token limits based on your business logic.
  • Building custom dashboards: Display usage metrics, cost breakdowns by model, and historical trends using the billing and time-series endpoints.
  • Monitoring usage: Query aggregated or per-key usage statistics to track costs and token consumption.
  • Managing containers programmatically: Create, validate, update, stop, start, and delete containers. Inspect and update deployments, wrap model weights, manage repository config and release builds, and manage org secrets, SSH keys, custom domains, and registry credentials.
If you need per-user usage metrics for billing, the recommended approach is to run a proxy server that tracks token counts via response headers — rather than creating a separate API key per user in your system.

Authentication

Admin API keys provide programmatic access to your account resources. Admin keys are prefixed with admin_ and must be included in the Authorization header as a Bearer token.
Need to create an admin API key? Follow our step-by-step guide: Getting a Tinfoil Admin Key
Admin keys provide programmatic access to organization settings, including managing API keys, reading billing data, and administering container resources. Do not share admin keys or expose them in browsers, client-side code, or public repositories. Revoke admin keys when team members with admin access leave your organization.

Available endpoints

This page covers the following endpoints:

API key management

  • GET /api/keys - List API keys
  • POST /api/keys - Create a new API key
  • POST /api/keys/update - Update an API key name or token cap
  • DELETE /api/keys/:key - Delete an API key

Billing & usage

  • GET /api/billing/usage - Get aggregated usage statistics for all keys
  • POST /api/billing/usage/key - Get usage statistics for a specific key
  • GET /api/billing/time-series - Get time series data
  • GET /api/billing/transactions - Get transaction history

Container endpoints

  • Lifecycle & deployment
    • POST /api/containers/validate-name - Validate a container name or custom domain before deploy
    • POST /api/containers/validate - Validate tinfoil-config.yml before deploy
    • GET /api/containers/hosts - List hosts available to the organization
    • GET /api/containers - List containers
    • GET /api/containers/:id - Get a specific container
    • POST /api/containers - Create a container
    • POST /api/containers/:id/relaunch - Relaunch a ready or failed container
    • POST /api/containers/:id/stop - Stop a running container
    • POST /api/containers/:id/start - Start a stopped container
    • DELETE /api/containers/:id - Delete a container
    • GET /api/containers/:id/update - Get in-progress update status
    • POST /api/containers/:id/update/accept - Promote a ready staged update
    • POST /api/containers/:id/update/cancel - Cancel an in-progress update
    • POST /api/containers/:id/github-connection - Toggle GitHub App connection
    • GET /api/containers/:id/metrics - Get resource metrics
  • Deployments
    • GET /api/deployments - List deployments with instance counts
    • PATCH /api/deployments/:id - Update deployment settings
    • POST /api/deployments/:id/update - Update all or selected instances
  • Model weights
    • POST /api/models/wrap - Start a model wrap job
    • GET /api/models/wrap - List wrap jobs
    • GET /api/models/wrap/:host/:job_id - Get wrap job status
    • DELETE /api/models/wrap/:host/:job_id - Delete a wrap job
  • GitHub repository operations
    • GET /api/github/repos/:owner/:repo/config - Read tinfoil-config.yml
    • POST /api/github/repos/:owner/:repo/config/pr - Open a config pull request
    • GET /api/github/repos/:owner/:repo/pulls/:number - Get pull request state
    • GET /api/github/repos/:owner/:repo/build/info - Get release and tag info
    • GET /api/github/repos/:owner/:repo/build/status - Get release workflow run status
    • POST /api/github/repos/:owner/:repo/build - Dispatch a release build
  • Related resources
    • GET /api/secrets - List org secrets
    • POST /api/secrets - Create an org secret
    • GET /api/secrets/:name - Get a secret’s metadata
    • PUT /api/secrets/:name - Update a secret
    • DELETE /api/secrets/:name - Delete a secret
    • GET /api/repositories/:owner/:repo/secrets - List repository secrets
    • POST /api/repositories/:owner/:repo/secrets - Create a repository secret
    • GET /api/repositories/:owner/:repo/secrets/:name - Get repository secret metadata
    • PUT /api/repositories/:owner/:repo/secrets/:name - Update a repository secret
    • DELETE /api/repositories/:owner/:repo/secrets/:name - Delete a repository secret
    • GET /api/ssh-keys - List org SSH keys
    • POST /api/ssh-keys - Create an SSH key
    • DELETE /api/ssh-keys/:name - Delete an SSH key
    • GET /api/domains - List custom domains
    • POST /api/domains - Add a domain
    • POST /api/domains/:domain/verify - Verify a domain
    • DELETE /api/domains/:domain - Delete a domain
    • GET /api/registry-credentials - List private registry credential status
    • PUT /api/registry-credentials/:registry - Create or update private registry credentials
    • DELETE /api/registry-credentials/:registry - Delete private registry credentials

API Key Management

List API Keys

endpoint
Returns all regular (non-admin) API keys in your organization. Keys you created are returned in full. Keys created by other members are masked (for example, tk_12345***).

Example Request

Response

Cost fields are reported in nanodollars (1000000000 = $1.00).

Create API Key

endpoint
Creates a new regular API key for your organization. Requires active token billing for the organization.

Request Body

string
required
Name for the API key. Must contain only alphanumeric characters, hyphens, underscores, spaces, and periods.
datetime
ISO 8601 timestamp when the key should expire. If not provided, the key doesn’t expire.
integer
Maximum number of tokens this key can use. If not provided, no limit is enforced.
object
Custom metadata to attach to the key. Maximum size: 5KB.
number
Maximum spend in dollars for this key. Must be at least 0.01. Omit or pass 0 for no cost limit.
integer
Maximum input tokens this key can consume. Omit or pass 0 for no limit.
integer
Maximum output tokens this key can consume. Omit or pass 0 for no limit.
boolean
default:"true"
Whether to send a notification when the key approaches max_tokens.
integer
default:"80"
Percentage of max_tokens at which the notification is sent. Must be between 1 and 100.

Example Request

Response

Update API Key

endpoint
Updates an existing regular API key in your organization. You can update any non-admin key in the organization, provided you have the full key value.

Request Body

string
required
The API key value to update, as returned by GET /api/keys.
string
New display name for the API key.
integer
New token cap for the key. Set this to 0 to clear the existing cap.
number
New spend cap in dollars. Set this to 0 to clear the existing cap.
integer
New input token cap. Set this to 0 to clear the existing cap.
integer
New output token cap. Set this to 0 to clear the existing cap.
boolean
Whether to send a notification when the key approaches max_tokens.
integer
Percentage of max_tokens at which the notification is sent. Must be between 1 and 100.

Example Request

Response

Delete API Key

endpoint
Deletes a regular API key in your organization. You can delete any non-admin key, provided you have the full key value.

Path Parameters

string
required
The API key value to delete (for example, tk_your_full_key_value_here).

Example Request

Response


Billing & Usage

Get Usage Statistics

endpoint
Retrieves aggregated usage statistics for your organization for the specified time period.

Query Parameters

string
Time preset for usage statistics. If omitted, returns all-time usage. Valid values: 5m, 15m, 30m, 1h, 24h, today, 7d, 30d, 60d, 90d, 180d, 365d, 3mo, 6mo, 12mo, all, and period (the organization’s current token billing period).
datetime
RFC 3339 start of an explicit range. Must be paired with end. Takes precedence over time.
datetime
RFC 3339 end of an explicit range. Must be paired with start. Future values are clamped to now. The range cannot exceed two years.

Example Request

Response

The keys object is grouped by API key name. cached_input_tokens counts the subset of input_tokens served from prompt cache.

Get Usage by Key

endpoint
Retrieves usage statistics for a specific regular API key in your organization.

Query Parameters

Accepts the same time, start, and end parameters as GET /api/billing/usage. If omitted, returns all-time usage.

Request Body

string
required
The API key value to query (for example, tk_your_full_key_value_here), as returned by GET /api/keys.

Example Request

Response

Get Time Series Data

endpoint
Retrieves time-series usage data for your organization over the specified period.

Query Parameters

string
default:"24h"
Time preset for the time series. Accepts the same presets as GET /api/billing/usage, including period. Explicit start and end parameters are also supported.
The bucket interval is derived from the span of the range: up to 5m5s, 15m15s, 30m30s, 1h1m, 24h15m, 7d2h, 30d8h, 365d24h, and longer ranges → 168h. Empty buckets are included as zero-value data points.

Example Request

Response

Get Transaction History

endpoint
Retrieves invoice and standalone charge history for your organization.
Viewing transaction history requires organization admin access. If the organization does not have a Stripe customer yet, the response is:

Example Request

Response


Containers

Admin API keys can access the same container APIs as a browser session, as long as the key belongs to the target organization.
Create, start, and relaunch operations require an active container subscription. Read-only endpoints and cleanup operations such as list, get, stop, and delete do not require an active subscription.
Private registry endpoints require private registry access to be enabled for the organization.

Scoped admin keys

Scoped admin keys use route action names in their allowed_actions list. The public container-related actions are: Container restrictions can set allowed owner/repo values and a container-name regular expression. Container lists return only matches, while reads and lifecycle operations reject nonmatching containers. Creates check the requested repository and name. A create request with replace_container_id also requires containers.delete access to the container being replaced. The CLI performs auxiliary requests. Container commands that resolve an ID or name require containers.read in addition to the operation’s action; name resolution uses the container list. Deployment get, settings, and update commands resolve through the deployment list and therefore require deployments.list. tinfoil login and tinfoil whoami verify credentials through the hosts route and require containers.hosts.read. Repository-level operations cannot always narrow access to one container name. Deployment routes are visible or allowed only when the repository matches and every existing instance matches the name restriction. Repository-secret and GitHub repository operations reject name-restricted keys. A key with any container repository or name restriction is also denied organization-wide container runtime status, organization secrets, SSH keys, custom domains, and registry credentials, even if containers.runtime-status.read, secrets.read, secrets.write, ssh-keys.read, ssh-keys.write, domains.read, domains.write, registry-credentials.read, or registry-credentials.write is listed.

Lifecycle & Deployment

Validate Container Name

endpoint
Checks whether a container name is valid and available for the current organization. You can also validate a custom domain before creating or relaunching a container.

Request Body

string
required
Container name. Must be lowercase alphanumeric with hyphens, max 64 characters.
boolean
Whether to validate the name for debug mode.
string
Custom domain to validate.
string
Existing container UUID when validating a relaunch that keeps the same custom domain.

Example Request

Response

Validate Container Config

endpoint
Validates the tinfoil-config.yml in a repository tag before create, replace, or relaunch.

Request Body

string
required
GitHub repository in owner/repo format.
string
required
Git tag to validate.
string
Existing container UUID. When present, instance-limit checks are skipped for relaunch validation.
string
Existing container UUID. When present, instance-limit checks are skipped for replace validation.

List Hosts

endpoint
Returns only hosts surfaced to the organization. If a default host is returned, it is marked is_default. Each host’s available_gpu_values is the intersection of the host’s capabilities and the organization’s GPU entitlement.

Response

List Containers

endpoint
Returns all containers in your organization. Responses may also include ssh_port, host_name, host_gpu_type, and host_cpu_type when available.

Example Request

Response

The cpus, memory_mb, and gpus response fields report the resources from the measured tinfoil-config.yml in the published release. Lifecycle request bodies do not override these resources.

Get Container

endpoint
Returns details for a specific container.

Path Parameters

string
required
The container UUID.

Example Request

Create Container

endpoint
Creates and deploys a new container. The repository must contain a tinfoil-config.yml at the specified tag.

Request Body

string
required
Container name. Must be lowercase alphanumeric with hyphens.
string
required
GitHub repository in owner/repo format.
string
required
Git tag to deploy. The tag must have a published GitHub release.
object
Saved per-instance environment variables as key-value pairs. These are separate from measured env values in tinfoil-config.yml.
string[]
Names of existing organization or repository secrets to inject.
string[]
Names of existing org SSH keys to inject.
boolean
Enable debug mode.
string
Verified custom domain for the container.
string
Target host name. Explicit selection requires host-selection access, and the host and requested GPU shape must be available to the organization.
string
Existing container UUID to replace. The old instance is stopped and removed before the replacement is queued. A later replacement failure does not restore the old instance.
boolean
Whether to request that an initial or changed selected tag be marked as the repository’s latest release after it becomes production-serving. The request applies only to a non-debug instance with a connected GitHub App and an active repository. Defaults to true.

Example Request

Response

Returns the created container object with status deploying. The container transitions to ready once the deployment completes.

Relaunch Container

endpoint
Relaunches a ready or failed container with a new tag, updated configuration, or both. Ready CPU-only and single-GPU container instances use a blue-green update flow. The dashboard may label ready as Running. Multi-GPU updates are disruptive, cannot use staging, and cannot be canceled after replacement starts.

Path Parameters

string
required
The container UUID.

Request Body

All fields are optional. Omitted fields keep their current values, except promote_release, which defaults to true for each operation.
string
New git tag to deploy.
object
New saved per-instance environment variables. This replaces the full saved map, but not measured env values in tinfoil-config.yml.
string[]
New saved manual secret selection. This replaces the previous manual selection, then merges with secrets declared in tinfoil-config.yml that exist in repository or organization scope.
string[]
New SSH key-name list. This replaces the full existing SSH key set.
boolean
Toggle debug mode.
string
Set or clear a custom domain. Pass an empty string to revert to the auto-generated domain.
string
Move a failed container instance to a different available host. A ready instance cannot move hosts during relaunch; stop it and use start instead.
boolean
Hold an eligible ready blue-green candidate for manual acceptance while the existing container instance serves production. Only ready CPU-only and single-GPU container instances support staging.
boolean
For a changed tag, whether to request that the selected tag become the repository’s latest release after it becomes production-serving. The request applies only to a non-debug instance with a connected GitHub App and an active repository. Defaults to true; eligibility begins after ready normally and after acceptance for a staging candidate.
Multi-GPU relaunches can change the repository tag. The control plane requests deletion of the current deployment and immediately queues its replacement, so this delete-and-queue flow has downtime.

Example Request

Stop Container

endpoint
Stops a running container. The container record is preserved and can be started again later.

Start Container

endpoint
Starts a stopped container, optionally with updated settings. Starting a stopped container cannot use staging.

Request Body

All fields are optional. Omitted fields keep their saved values, except promote_release, which defaults to true for each operation.
string
Git tag to deploy.
object
Saved per-instance environment variables. This replaces the full saved map, but not measured env values in tinfoil-config.yml.
string[]
New saved manual secret selection. This replaces the previous manual selection, then merges with secrets declared in tinfoil-config.yml that exist in repository or organization scope.
string[]
SSH key-name list. This replaces the full saved SSH key set.
boolean
Toggle debug mode.
string
Set or clear a custom domain. Pass an empty string to revert to the auto-generated domain.
string
Move the stopped container instance to a different available host. Host access and GPU entitlement are rechecked.
boolean
For a changed tag, whether to request that the selected tag become the repository’s latest release after the container instance reaches ready and becomes production-serving. The request applies only to a non-debug instance with a connected GitHub App and an active repository. Defaults to true.

Delete Container

endpoint
Permanently deletes a container and its running enclave. The deployment remains while it has other instances. Outstanding billing is finalized before deletion.
Returns 204 No Content on success.

Get Update Status

endpoint
Returns the status of an in-progress relaunch or restart.

Response

If no update is in progress:
Candidate statuses are pending (queued), deploying (submitted and booting), started (the enclave is running and startup checks are in progress), ready (healthy and ready for traffic or staging acceptance), and failed (deployment or startup checks failed).

Accept Update

endpoint
Accepts a ready staging candidate, switches production traffic to it, and returns the updated container.

Cancel Update

endpoint
Cancels an in-progress update and returns 204 No Content. Multi-GPU updates cannot be canceled once started.

Toggle GitHub App Connection

endpoint
Sets whether the container is connected to a GitHub App installation for its repo owner.

Request Body

boolean
required
Whether GitHub App connectivity should be enabled.

Get Container Metrics

endpoint
Returns CPU, GPU, and memory utilization time series for a container.

Query Parameters

string
default:"24h"
Time preset. Valid values: 5m, 15m, 30m, 1h, 24h, today, 7d, 30d, 60d, 90d, 180d, 365d, 3mo, 6mo, 12mo, all.
The response contains data_points and interval. Utilization values are average and maximum percentages for each bucket; memory totals report the corresponding CPU or GPU capacity.

Deployments

A repository deployment contains all container instances in an organization that use the same GitHub repository. New repository deployments have default_staging=false.

List Deployments

endpoint
Returns deployments with aggregate instance counts and settings.
deploying_count combines instances in pending, deploying, started, and stopping states. There is no separate GET /api/deployments/:id endpoint. Resolve a deployment by ID or repository from the list response.

Update Deployment Settings

endpoint
Updates shared settings and returns the deployment.
boolean
Default staging behavior for eligible repository deployment updates.

Update Deployment Instances

endpoint
Updates every eligible instance, or a selected set, to one repository tag.
string
required
Repository release tag to deploy.
boolean
Staging override for this request. Omit it to use default_staging; an explicit value overrides the saved default for this update only.
boolean
For selected instances changing tags, whether to request that the selected tag become the repository’s latest release after an instance becomes production-serving. The request applies only to non-debug instances with a connected GitHub App and an active repository. Defaults to true; eligibility begins after ready for normal updates and after acceptance for staging candidates.
string[]
Container UUIDs to update. Omit it to update every instance.
The response contains one result per targeted instance with status updating, skipped, or failed. Only instances in backend status ready or failed are eligible; the dashboard may label ready as Running. Instances in other states, or with an update already in progress, are skipped. When staging is requested, unsupported selected instances return failed; they are not updated without staging.

Example Request

Model Weights

These endpoints back the tinfoil model CLI commands. They wrap Hugging Face model weights into verified artifacts that GPU containers load with integrity checking. See Model weights for the workflow. Access requires a GPU entitlement or model view access for the organization.

Wrap Model

endpoint
Starts a wrap job on a host and returns 202 Accepted with the job. If a job for the same repository, commit, and schema is already pending or running on that host, the existing job is returned instead of starting a new one.

Request Body

string
required
Hugging Face repository, for example google/gemma-4-31B-it.
string
required
Target host name. The host must be available to the organization.
string
Repository commit to wrap. Defaults to the head of the default branch.
string
Hugging Face access token for gated or private repositories.
integer
Pack schema version. Omit or pass 0 for the default.

Response

Completed jobs also include schema, image_digest, root_hash, offset, verity_uuid, and ended_at. Failed jobs include error.

List Wrap Jobs

endpoint
Returns wrap jobs across the organization, newest first.
integer
default:"20"
Maximum number of jobs to return, between 1 and 200.

Get Wrap Status

endpoint
Returns the current status of one wrap job, fetched live from the host. Includes logs when available.

Delete Wrap Job

endpoint
Deletes a wrap job and its artifact once no container references it. Returns 204 No Content, or 409 Conflict if the artifact is still in use.

GitHub Repository Operations

These endpoints back the tinfoil repo CLI commands. They read and update a repository’s tinfoil-config.yml, and trigger and monitor release builds. The repository must be accessible through the organization’s GitHub App installation. Name-restricted scoped admin keys are denied.

Get Repository Config

endpoint
Returns the tinfoil-config.yml from the default branch, both parsed and raw.

Response

Open Config Pull Request

endpoint
Writes an updated tinfoil-config.yml to a new branch and opens a pull request against the default branch. The branch name, commit message, and PR title are generated server-side.

Request Body

Provide exactly one of config or raw.
object
Structured config fields to apply. Managed keys are updated in place and unmanaged keys in the existing file are preserved.
string
Complete YAML document to write verbatim. Must parse as a valid config.
string
Pull request description.

Response

Get Pull Request

endpoint
Returns the state of a pull request: pr_number, state, merged, and pr_url.

Get Build Info

endpoint
Returns release and tag information used to plan the next build.

Response

has_new_commits is false only when the default branch head is exactly the commit tagged by the latest release.

Get Build Status

endpoint
Returns the release workflow run for a version, or run: null if no matching run exists yet. Returns 404 if the repository has no .github/workflows/tinfoil-release.yml.
string
Semver tag to look up, for example v1.2.1. If omitted, returns the most recent run.

Response

Dispatch Build

endpoint
Triggers the repository’s tinfoil-release.yml workflow for a version.
string
required
Semver string such as v1.2.1. A leading v is added if missing.

Response

Secrets

Organization and repository secrets are encrypted values injected into containers at deploy time. Secret names must be UPPER_SNAKE_CASE or kebab-case.
endpoint
Returns all org-level secrets as metadata only. Secret values are never returned.
endpoint
Returns metadata for a single secret, including which containers use it.
endpoint
Creates a new organization-scoped secret.

Request Body

string
required
Secret name.
string
required
Secret value.
Use POST /api/repositories/:owner/:repo/secrets with the same request body to create a repository-scoped secret. The corresponding repository GET, PUT, and DELETE endpoints use /api/repositories/:owner/:repo/secrets/:name.
endpoint
Updates the value of an existing org secret.
endpoint
Deletes an org secret. If the secret is currently used by any container, the API returns 409 Conflict and includes the blocking container names.

SSH Keys

SSH key names must be kebab-case, for example my-deploy-key.
endpoint
Returns all org-level SSH keys.
endpoint
Adds a new org SSH key for debug-mode containers.

Request Body

string
required
SSH key name in kebab-case.
string
required
SSH public key, for example ssh-ed25519 AAAA....
endpoint
Deletes an org SSH key. If the key is currently used by any container, the API returns 409 Conflict and includes the blocking container names.

Custom Domains

endpoint
Returns all custom domains for the organization, including verification details and which containers use each domain.
endpoint
Adds a custom domain for verification and returns the TXT and CNAME records required for setup.

Request Body

string
required
Domain name to register, for example api.example.com.
endpoint
Checks DNS records and updates the domain’s verification state.
endpoint
Deletes a custom domain. If the domain is currently used by any container, the API returns 409 Conflict and includes the blocking container names.

Registry Credentials

Private registry credentials are supported for ghcr, gcr, and dockerhub.
endpoint
Returns credential status for each supported registry, including whether credentials exist, whether they are expired, and when they were last updated.
endpoint
Creates or updates credentials for a supported registry.

Path Parameters

string
required
Registry identifier: ghcr, gcr, or dockerhub.

Request Body

For ghcr:
For gcr:
For dockerhub:
endpoint
Deletes credentials for a supported registry.

Error Responses

Example error response:
Common error codes: