Skip to main content

Introduction

The Admin API lets you manage regular API keys and inspect billing data for a personal account or organization. Organization admin keys also provide access to container-related APIs. Personal admin keys access only the creator’s personal resources, even if the creator belongs to an organization. Organization admin keys access only their organization. Select Personal or the target organization in the dashboard before creating a key; organization keys require an admin role in that organization. Creating an admin key requires a signed-in user session, not another admin key. It does not require active API billing, but creating regular inference keys still requires active token billing for the account. Existing personal admin keys remain valid.

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, deploy, update, stop, and delete instances. Inspect and update projects, 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, run a proxy server that tracks token counts via response headers instead of creating a separate API key per user.

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 personal or organization resources, including managing API keys and reading billing data. Container resources require an organization admin key. 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:

Caller identity

  • GET /api/auth/context - Inspect the authenticated personal or organization context

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’s name, expiration, limits, or notifications
  • 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/update/plan - Preview a running instance’s update without deploying
    • POST /api/containers/:id/update - Update a running container to a new tag or configuration
    • POST /api/containers/:id/stop - Stop a running container
    • POST /api/containers/:id/deploy - Deploy a stopped or failed container
    • DELETE /api/containers/:id - Delete a container
    • GET /api/containers/:id/update - Get in-progress update status
    • POST /api/containers/:id/update/promote - Switch traffic to a held update that is ready
    • 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
  • Projects
    • GET /api/containers/projects - List projects with instance counts
    • PATCH /api/containers/projects/:id - Update project settings
    • POST /api/containers/projects/:id/update/plan - Preview updates for all or selected instances without deploying
    • POST /api/containers/projects/: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

The response examples in this section use organization admin keys. Personal inference-key responses omit is_owner.

List API Keys

endpoint
Returns regular (non-admin) API keys for the key’s account. Personal admin keys return only the creator’s personal keys, in full. Organization admin keys return all organization keys; 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 the admin key’s personal account or organization. Requires active token billing for that account.

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.
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 email the key owner as any configured cap is approached or reached.
integer
default:"80"
Percentage of a cap at which the warning is sent. Must be between 1 and 100.
The three caps are independent lifetime totals. When any one is reached, inference requests with the key fail with 429 and code: insufficient_quota. See Quota errors.

Example Request

Response

Update API Key

endpoint
Updates an existing regular API key. Personal admin keys can update only the creator’s personal inference keys. Organization admin keys can update regular keys in their organization. Requires the full key value; admin keys cannot be updated through admin-key authentication.

Request Body

string
required
The API key value to update, as returned by GET /api/keys.
string
New display name for the API key.
datetime | null
New expiration as an RFC 3339 timestamp in the future. Pass null to make the key non-expiring. Omit to leave it unchanged.
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 email the key owner as any configured cap is approached or reached.
integer
Percentage of a cap at which the warning is sent. Must be between 1 and 100.

Example Request

Response

Delete API Key

endpoint
Deletes a regular API key. Personal admin keys can delete only the creator’s personal inference keys. Organization admin keys can delete regular keys in their organization. Requires the full key value; admin keys cannot be deleted through admin-key authentication.

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 the admin key’s personal account or 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 account’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 the admin key’s personal account or 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 the admin key’s personal account or 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 5m → 5s, 15m → 15s, 30m → 30s, 1h → 1m, 24h → 15m, 7d → 2h, 30d → 8h, 365d → 24h, 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 the admin key’s personal account or organization.
Viewing organization transaction history requires organization admin access. If the organization does not have a Stripe customer yet, the response is:

Example Request

Response


Authenticated context

GET /api/auth/context returns the effective caller identity without listing organization resources. It is available to authenticated organization and personal admin keys, including scoped keys without container-host permissions. The CLI uses it for login and whoami. The response contains user_id, context_type (organization or personal), and organization: an object containing id for organization context, or null for personal context. It does not return secret key material or an organization name. Use the returned context rather than inferring an organization from the key string.

Containers

Organization admin API keys can access the same container APIs as a browser session, as long as the key belongs to the target organization. Personal admin keys cannot access these organization-only resources.
Create, deploy, and update 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. Creating an instance requires containers.validate as well as containers.create: the CLI validates the configuration and mount assignments before creating anything. It sends the proposed name as instance_name, so name-restricted keys can validate a matching create without gaining access to other names. Container commands that resolve an ID or name require containers.read in addition to the operation’s action; name resolution uses the container list. Project get, settings, and update commands resolve through the project list and therefore require containers.projects.read. Update planning uses the same action permission as the corresponding update. tinfoil login and tinfoil whoami use authenticated context, not the hosts route. Repository-level operations cannot always narrow access to one container name. Project 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, registry credentials, and model weights, even if containers.runtime-status.read, secrets.read, secrets.write, ssh-keys.read, ssh-keys.write, domains.read, domains.write, registry-credentials.read, registry-credentials.write, or any models.* action is listed. Some endpoints have no action name and are reachable only by unscoped admin keys. A scoped key receives 403 Forbidden on all API key management routes (/api/keys), on the billing usage, time-series, and transaction routes, and on POST /api/containers/validate-name. Use an unscoped admin key for key management and billing automation.

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 updating 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 an update 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 update.

Request Body

string
required
GitHub repository in owner/repo format.
string
required
Git tag to validate.
string
Proposed name when validating a new instance. Required for a name-restricted admin key when no existing instance ID is supplied. The name and repository must both match the key’s restrictions. For update or replacement validation, authorization uses the existing instance’s stored name and ownership, not this proposed name.
string
Existing container UUID. When present, instance-limit checks are skipped for update 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 a new instance and deploys it unless the config declares volume mounts. 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 Tinfoil-managed organization or repository secrets to inject. For non-debug private-keyserver delivery, omit this field or send []; private names come from the measured config, not this selection.
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 mark an initial or changed selected tag as the repository’s latest GitHub release once the container is running and serving production. Applies only to a non-debug instance with a connected GitHub App and an active repository. Defaults to true.

Example Request

Response

Without declared volume mounts, returns the created instance with status deploying; it transitions to running once deployment completes. With declared mounts, returns stopped and volume_slots, the named mounts from the config. Attach the selected disks, then call Deploy. A disk is required only for a mount with key_secret; optional mounts may remain empty. See persistent volumes. Every container object carries update_strategy, either blue_green or replace, for its saved configuration. Update requests also check the target release, which may require a different strategy. The connections object contains production and review, each either null when unavailable or an object with url, repo, and tag. Review describes the current blue/green candidate, including its review port and target tag, not the production connection. Use these values with a verified client; merely opening the URL is not attestation verification. A connection descriptor does not make a debug enclave confidential.

Plan an update

POST /api/containers/:id/update/plan accepts the same body as Update Container and returns a read-only current-to-target plan without deploying. It requires containers.update and the same organization, repository, and instance-name authorization as execution. The plan includes read_only, instance_id, name, current and target resource objects (tag, cpus, memory_mb, gpus), update_strategy, downtime_required, hold, hold_source (project or request), hold_available, mark_latest_release, and volume_data (retained). configuration_changes reports added, changed, and removed names for variables, secrets, and ssh_keys, changed settings, and secrets_refreshed; values are not exposed. cost_estimate.available indicates whether an estimate is available, with reason when it is not. A plan can report an unavailable hold or required downtime without requiring consent to inspect it. Execution still requires a valid hold choice and downtime consent, and revalidates the request. The plan is not a reservation or a historical snapshot.

Secret delivery in update plans

When the target config has a nonempty keyserver-url, an instance plan includes the optional secret_delivery object. In a project plan it is nested at results[].plan.secret_delivery, not at the project response’s top level. The object is omitted for configs without keyserver-url; absence is not evidence that external secrets have been verified. For a non-debug private target, the object has this shape:
Both name lists are arrays, never null. The object contains no endpoint URL, secret values, or bootstrap credentials. Registry authentication, certificate authorization, and debug SSH are separate from these workload-secret lists. Request secrets always means a managed selection. On deploy/update, omitted or null selections retain saved bindings; send "secrets": [] explicitly when switching to private delivery. Nonempty managed selections and private names supplied in saved/request variables are rejected. There is no implicit fallback to managed values. In config-validation responses, YAML keyserver-url appears at config.keyserver_url, model key-secret at config.models[].key_secret, volume key-secret at config.volumes[].key_secret, and dummy attestation at config.shim.dummy_attestation. Invalid keyserver URL syntax returns a validation error with field: "keyserver_url" and code: "invalid_keyserver_url". See private-secret requirements.

Update Container

endpoint
Replaces the version a running container serves with a new tag, updated configuration, or both. The server evaluates the target release and volume configuration to choose the strategy. For a blue/green update (single GPU or CPU-only, no persistent volumes), the new version boots alongside the current one and traffic switches once it is ready. For a replacement update (multi-GPU or persistent volumes), the running instance stops first and the new version deploys in its place; the request must carry confirm_downtime: true and cannot be held for review. Containers in any other status return 409 with code INVALID_CONTAINER_STATE; use Deploy for stopped or failed containers.

Path Parameters

string
required
The container UUID.

Request Body

All fields are optional. Omitted fields keep their current values, except mark_latest_release, which defaults to true for each operation, and hold, which inherits the project’s current hold_by_default setting.
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 Tinfoil-managed secret selection. Omitted or null retains the saved selection. In managed delivery, a supplied list replaces it, then merges with declared secrets that exist in repository or organization scope. Non-debug private delivery requires an empty managed selection: send [] explicitly to clear existing bindings; declared private values stay in your keyserver.
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.
boolean
Hold the new version for review and promotion while the current instance keeps serving production. Available only for a blue/green update; requesting a hold when the target release requires replacement returns 400 with code HOLD_UNAVAILABLE. Omit to inherit the project default; explicit true or false applies to this operation only and does not modify project settings.
boolean
Required to be true when the target update requires replacement. Without it the request returns 409 with code DOWNTIME_CONFIRMATION_REQUIRED and the update is not started.
boolean
For a changed tag, whether to mark the selected tag as the repository’s latest GitHub release once the new version is running and serving production, or after promotion for a held version. Applies only to a non-debug instance with a connected GitHub App and an active repository. Defaults to true.
A running container cannot change hosts during an update; stop it, then deploy it with host_name. A blue/green update of a single-GPU container needs a second free GPU on the container’s host for the new version. When none is free the request returns 409 with code HOST_GPU_BUSY and the running instance is untouched. CPU-only updates have no such requirement.

Example Request

Stop Container

endpoint
Stops a running container and removes its DNS records. The container record, saved configuration, and attached volumes are preserved so it can be deployed again later.

Deploy Container

endpoint
Boots a new enclave for a stopped or failed container, optionally with updated settings. A stopping container queues the deploy behind the stop without changing its tag or host; wait until stopped to change either. Deploys go straight to production and cannot be held for review. A running container returns 409 with code INVALID_CONTAINER_STATE; use Update instead.

Request Body

All fields are optional. Omitted fields keep their saved values, except mark_latest_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 Tinfoil-managed secret selection. Omitted or null retains the saved selection. In managed delivery, a supplied list replaces it, then merges with declared secrets that exist in repository or organization scope. Non-debug private delivery requires an empty managed selection: send [] explicitly to clear existing bindings; declared private values stay in your keyserver.
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
Deploy the container on a different available host. Host access and GPU entitlement are rechecked. Attached volumes must be on the target host.
boolean
For a changed tag, whether to mark the selected tag as the repository’s latest GitHub release once the container instance is running and serving production. Applies only to a non-debug instance with a connected GitHub App and an active repository. Defaults to true.

Delete Container

endpoint
Permanently deletes an instance and its running enclave. The project 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 update.

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 held and waiting for promotion), and failed (deployment or startup checks failed).

Promote Update

endpoint
Promotes a held version ready for promotion (update_status: "ready"), switches production traffic to it, and returns the updated container.

Cancel Update

endpoint
Cancels an in-progress or failed update and returns 204 No Content. Updates whose strategy is replace cannot be canceled once the running instance has been stopped.

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.

Projects

A project contains all container instances in an organization that use the same GitHub repository. It is created implicitly by the first instance or project-secret namespace; there is no explicit project-create endpoint. New projects have hold_by_default=false, inherited by individual and batch updates when hold is omitted.

List Projects

endpoint
Returns projects with aggregate instance counts and settings. A project groups the instances that share one config repository.
deploying_count combines instances in pending, deploying, started, and stopping states. There is no separate GET /api/containers/projects/:id endpoint. Resolve a project by ID or repository from the list response.

Update Project Settings

endpoint
Updates shared settings and returns the project.
boolean
Whether updates of this project hold new versions for review by default.

Update Project Instances

To inspect the same selection before updating, POST /api/containers/projects/:id/update/plan accepts the request body below and uses containers.projects.update authorization. It returns read_only, project_id, latest_release_tag, eligible/skipped/failed counts, and per-instance results with instance_id, name, status (planned, skipped, or failed), plan, and error. A planned result contains the same instance plan; skipped and failed results explain why no plan is available.
endpoint
Updates every running instance, or a selected set, to one repository tag.
string
required
Repository release tag to deploy.
boolean
Holding for review override for this request. Omit it to use hold_by_default; an explicit value overrides the saved default for this update only.
boolean
For selected instances changing tags, whether to mark the selected tag as the repository’s latest GitHub release once an instance is running and serving production, or after promotion for held versions. Applies only to non-debug instances with a connected GitHub App and an active repository. Defaults to true.
string[]
Container UUIDs to update. Omit it to update every instance.
boolean
Required to be true when any eligible targeted instance requires replacement for the target release. Without it the whole request returns 409 with code DOWNTIME_CONFIRMATION_REQUIRED and lists the affected instances; no instance is updated.
If preflight finds an eligible instance whose target release requires replacement and hold is requested, the whole request returns 400 with code HOLD_UNAVAILABLE and lists the affected instances; no instance is updated. After preflight, the response contains one result per targeted instance with status updating, skipped, or failed. Only running instances are updated; stopped and failed instances are skipped (bring them up with Deploy), as are instances with an update already in progress.

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: Container lifecycle codes. The error message says what to do next; show it to the user as is.