Credentials

Credentials give your app keys and connections that belong to an external service: an API key for Acme, an OpenAI key, a Google sign-in. Each user supplies their own, and the platform passes them to your app at run time.

A value that belongs to no service, such as a webhook signing token, is a plain secret instead.

→ Concepts: providers, credentials, secrets and vaults


Declaring credentials

List them under credentials: in inf.yml. Each entry names a provider, a capability, or both.

API keys from a provider

Name the provider and the keys your app reads:

yaml
1credentials:2  - provider: acme3    name: Acme CRM4    website: acme.com5    secrets: [ACME_API_KEY]6    description: Syncs contacts from your Acme workspace

When a user runs the app without an Acme key, the run stops and asks for ACME_API_KEY. The key they paste is saved as their workspace's Acme CRM credential. Its logo comes from acme.com, and it shows in the vault like any other connection. Later runs, and any other app that asks for acme, find it there.

The provider doesn't have to be one the platform lists. name and website describe it for users who haven't added it yet. For a provider the platform lists, such as openai, leave them out; the platform's name and logo win.

Who can list a provider for everyone

The platform's provider catalog is shared by every workspace, so only platform apps can add to it:

  • A platform app (owned by a platform admin) that declares a provider the catalog doesn't have adds it on deploy, with the given name and the logo from website. Every workspace then sees it in the vault, ready to connect. This happens the same way platform apps are approved in the store automatically.
  • Any other app doesn't change the catalog. The provider still works for each workspace that runs the app: the key a user saves becomes their workspace's credential for it, under the app's name and logo. It just isn't listed for workspaces that haven't used it.

This keeps slugs from being claimed by whoever deploys first. To get a provider listed for everyone, ask a platform admin.

Leave out secrets to receive every key the provider's credential holds.

OAuth capabilities

For a service users sign in to, name the capability. It decides the access (the OAuth scopes) your app gets:

yaml
1credentials:2  - key: google.sheets3    description: Read and write your sales sheets45  - key: google.drive6    description: Attach exported files7    optional: true

Users without a Google connection are asked to connect one. Users who have one without Sheets access are asked to grant it.

Properties

PropertyTypeDescription
providerstringSlug of the provider whose credential supplies the keys, such as acme or openai. Lowercase letters, digits and single hyphens.
namestringDisplay name for a provider the platform doesn't list
websitestringThe provider's website, where its logo comes from (acme.com)
secretsstring[]Keys to pass to the app from the credential. They are also the fields users fill in when the key is missing.
keystringA capability of a provider the platform defines (google.sheets, x.tweet.write). When set, it decides how the entry is checked.
scopesstring[]OAuth scopes to require from the provider's credential, for an entry without key
descriptionstringShown to users when the credential is missing
optionalbooleanIf true, the app runs without it

Each entry needs provider or key. A deploy with an invalid provider fails with a validation error.

The section was called integrations: before 2026-09-23. Current belt refuses that name and asks you to rename it.


Available capabilities

List the capability keys the platform defines:

bash
1belt app credentials list

Common capabilities

KeyDescription
google.sheetsRead/write Google Sheets
google.sheets.readonlyRead-only Sheets access
google.driveGoogle Drive files
google-sa.filesService account access (Sheets, Docs, Drive)
microsoft.mail.readRead Outlook email
notion.readRead shared Notion pages
salesforce.apiSalesforce REST API access
reddit.readRead Reddit posts and comments

→ Credentials overview for setup guides (Google, Slack, Microsoft, Notion, Salesforce, Reddit, and more)


Accessing credentials

API keys

Each key listed under secrets arrives as an environment variable with the same name:

1import os23class App(BaseApp):4    async def setup(self, config):5        self.acme_key = os.environ["ACME_API_KEY"]

OAuth Credentials

1import os, json23class App(BaseApp):4    async def setup(self, config):5        creds_json = os.environ.get("GOOGLE_OAUTH_CREDENTIALS")6        if creds_json:7            self.credentials = json.loads(creds_json)

Service Account

1from google.oauth2 import service_account23sa_json = os.environ.get("GOOGLE_SA_CREDENTIALS")4if sa_json:5    self.credentials = service_account.Credentials.from_service_account_info(6        json.loads(sa_json)7    )

Secrets vs credentials

secrets:credentials:
The value belongs toNo serviceA provider
Users seeA key name to fill inThe provider, with its name and logo
Stored asA plain secretThat provider's credential, with a scope and a status
Reused byApps that ask for the same key nameEvery app that asks for the provider
Best forWebhook tokens, feature flagsAPI keys, OAuth sign-ins

Check before run

Validate that your workspace has the secrets and credentials an app requires before calling POST /run:

POST /credentials/check

Requires credentials:read scope. Send the same secrets and credentials arrays from your app's inf.yml:

bash
1curl -X POST https://api.inference.sh/credentials/check \2  -H "Authorization: Bearer inf_your_key" \3  -H "Content-Type: application/json" \4  -d '{5    "secrets": [{ "key": "WEBHOOK_SECRET" }],6    "credentials": [7      { "provider": "acme", "secrets": ["ACME_API_KEY"] },8      { "key": "google.sheets" }9    ]10  }'

When requirements are missing, the response matches the 412 body from POST /run (satisfied: false and an errors array). See REST overview — Missing requirements.

Connect from the CLI

Connect native OAuth and service-account providers without the dashboard:

bash
1belt credentials connect google2belt credentials connect slack3belt credentials disconnect google

For MCP connector servers, use belt mcp connect <slug> instead. List connected services with belt credentials list (belt creds is an alias).

When a provider supports multiple connection types (Google has OAuth at google and a separate service account at google-sa), use the provider key that matches the connection you need. Connect a Google service account from vaults → credentials (google-sa slug) or with belt credentials connect google-sa.

When you run an app or agent and requirements are still missing, the CLI prints the same errors[] categories with actionable commands — for example belt secrets set OPENAI_API_KEY <value> or belt credentials connect google.

→ CLI setup: Credentials · Credentials API


Best Practices

  1. Request minimal scopes - use readonly if you only read
  2. Clear descriptions - explain why access is needed
  3. Handle missing gracefully - check if optional credentials exist
  4. Test without - ensure app works without optional credentials

REST API

Programmatic connect, disconnect, and requirements checks:

→ Credentials API — POST /credentials, POST /credentials/check, MCP tool proxy


Next

→ Troubleshooting - Common issues and solutions

we use cookies

we use cookies to ensure you get the best experience on our website. for more information on how we use cookies, please see our cookie policy.

by clicking "accept", you agree to our use of cookies.
learn more.