# Vault

> The credentials a member holds: list them, connect new ones through a hosted link, and fetch a fresh token to call the third-party API yourself.

Source: https://docs.generalinput.com/api/vault



The vault holds the workspace's connected accounts. Through the API it does three things, each behind its own scope, so a key can be given exactly the reach it needs.

| Endpoint                                                   | Scope           | Does                                                             |
| ---------------------------------------------------------- | --------------- | ---------------------------------------------------------------- |
| [`GET /v1/credentials`](/api/vault/list-credentials)       | `vault:read`    | Credentials the member can use, with env var names. No secrets.  |
| [`GET /v1/credentials/:id`](/api/vault/get-credential)     | `vault:read`    | One credential's fields, scopes, and sharing.                    |
| [`POST /v1/credentials/:id/token`](/api/vault/issue-token) | `vault:token`   | A fresh access token or API key. Audited with your reason.       |
| [`POST /v1/connections`](/api/vault/create-connection)     | `vault:connect` | Start connecting a service; get a link for a person to complete. |
| [`GET /v1/connections/:id`](/api/vault/get-connection)     | `vault:connect` | Poll a connection until it carries a credential id.              |

## What the vault does and does not do [#what-the-vault-does-and-does-not-do]

**It hands out tokens; it never brokers calls.** There is no request proxy. You fetch a token, then call Slack, Stripe, or HubSpot directly with it. Enforcement (rate limits, scopes, what the token may touch) is the third-party API's and yours.

**Every token issue is audited.** The `reason` you pass lands in the credential access log next to the member the key acts as, exactly as an agent's `bash` call would. Make it specific.

**Refresh tokens never leave.** A token response carries the usable fields (`accessToken`, `apiKey`, `instanceUrl`, and so on). The vault keeps the refresh token and refreshes on your behalf; call [issue a token](/api/vault/issue-token) again when `expiresAt` passes.

**Only a platform API key opens the vault.** The three `vault:` scopes belong to platform keys alone, so a personal (`gi_sk_`) key gets `403 Insufficient scope` from every route here. A CLI session reaches them as the signed-in member.

**Access follows the member.** A platform API key sees what its creator owns or has been granted. A credential shared with that member as viewer-only lists fine but refuses a token with `403`.

## Connecting a service without a browser of your own [#connecting-a-service-without-a-browser-of-your-own]

An instance or an agent cannot complete an OAuth dance itself. [Create a connection](/api/vault/create-connection) returns a hosted `connectUrl`. Hand it to the person; they finish the connection on the dashboard, signed in as the same member. [Poll the connection](/api/vault/get-connection) until `status` is `connected` and read `credentialId`. Connections expire after one hour.
