The TypeScript SDK
Install @1claw/sdk, create a client, and fetch a secret using the {data, error} response envelope.
The SDK gives Node apps and agents typed, full-parity access to the API. Every call returns an envelope so you check for errors without try/catch everywhere.
Auth options when creating a client: a personal API key (apiKey: '1ck_...') for server-side work, agent credentials (agentId + apiKey: 'ocv_...') which the SDK exchanges for a JWT and refreshes automatically, or manual login.
- 1
Install the SDK in a Node 20+ project.
bashnpm install @1claw/sdk - 2
Set your key and vault ID in the environment so they stay out of source. Use your vault UUID from
1claw vault list.bashexport ONECLAW_API_KEY="1ck_your_key" export ONECLAW_VAULT_ID="your-vault-uuid" - 3
Write a script that creates a client and fetches a secret. Check res.error before using res.data. Use a path that exists in your vault, such as
api-keys/openaifrom Foundations. Create one with1claw secret setif needed. Save the code above asfetch-secret.ts.typescriptimport { createClient } from "@1claw/sdk"; async function main() { const client = createClient({ baseUrl: "https://api.1claw.co", apiKey: process.env.ONECLAW_API_KEY, }); const res = await client.secrets.get(process.env.ONECLAW_VAULT_ID!, "api-keys/openai"); if (res.error) { console.error(res.error.message); } else { console.log(res.data.value); } } main(); - 4
Run it.
bashnode --experimental-strip-types fetch-secret.ts
Every method returns { data, error, meta }. Typed error classes like AuthError (401), NotFoundError (404), and RateLimitError (429) are exported from @1claw/sdk if you prefer to switch on the type.
You have a running script that authenticates with the SDK and prints a fetched secret value. That's the foundation for any Node service or agent that needs vault access.
Where this goes wrong in practice. The SDK is a thin client over the API, and most problems come from treating its return values casually.
- The response envelope is ignored. Every call resolves to { data, error, meta }, so destructuring domain fields directly yields undefined rather than throwing, and the bug surfaces somewhere unrelated.
- Errors are assumed to be exceptions. A 402 payment-required or an approval-required response arrives as a value in error, not as a rejected promise, and a try/catch alone will not see it.
- The client is constructed per request. It is designed to be long-lived and to manage token exchange and refresh; rebuilding it per call re-authenticates constantly and defeats that.
- Secret values are logged during debugging. A console.log of a whole response object prints the value, and that line survives into production more often than anyone admits.
Check error before reading data on every call. It is more verbose than optimistic destructuring and it is the difference between a clear failure and a silent undefined.
Check your understanding
3 questionsWhat shape does every SDK method return?
How do you construct a client for server-side work with a personal key?
When you pass agentId + apiKey (ocv_) to createClient, what does the SDK handle for you?