Keys API
Below is a comprehensive REST API documentation for the Keys resource, now including an important note referencing the key creation logic from GitHub.
All examples assume the base URL https://app.openagentsbuilder.com
.
Note: There is an API client plus example available on: https://github.com/CatchTheTornado/open-agents-builder-client and https://github.com/CatchTheTornado/open-agents-builder-example
1. Overview
Keys typically store:
keyLocatorHash
: A unique 64-char hash that identifies the key.keyHash
: A 32+ char string representing a hashed form of the key.encryptedMasterKey
: The actual key contents (encrypted).databaseIdHash
: The database this key belongs to.acl``,
extra**, and **
expiryDate`: Additional metadata or permission details.
The system provides three main operations:
GET /api/keys
: Lists or filters keys.PUT /api/keys
: Creates or updates a key bykeyLocatorHash
(requires owner role).DELETE /api/keys/[key]
: Deletes a key bykeyLocatorHash
(requires owner role).
2. Data Schema: KeyDTO
From keyDTOSchema
:
export const keyDTOSchema = z.object({ displayName: z.string().min(1), keyLocatorHash: z.string().min(64).max(64), keyHash: z.string().min(32), keyHashParams: z.string().min(1), databaseIdHash: z.string().min(64).max(64), encryptedMasterKey: z.string().min(1), acl: z.string().nullable().optional(), extra: z.string().nullable().optional(), expiryDate: z.string().nullable(), updatedAt: z.string().default(() => getCurrentTS()),});export type KeyDTO = z.infer<typeof keyDTOSchema>;
Key fields:
keyLocatorHash
: 64-char unique identifier (primary).keyHash
: A 32+ char hashed representation.encryptedMasterKey
: The encrypted key material.databaseIdHash
: A 64+ char reference to your database.acl
,extra
,expiryDate
: Additional or optional fields.displayName
: A friendly name.
3. Endpoints
3.1 GET /api/keys
3.1.1 Description
Lists all keys for the current database, or can filter by:
keyLocatorHash
keyHash
databaseIdHash
3.1.2 cURL Example
curl -X GET \ "https://app.openagentsbuilder.com/api/keys?databaseIdHash=35f5c5b139a6b5..." \ -H "Authorization: Bearer <YOUR_API_KEY>" \ -H "database-id-hash: 35f5c5b139a6b5..."
3.1.3 TypeScript (fetch) Example
async function listKeys(databaseIdHash: string) { const response = await fetch( `https://app.openagentsbuilder.com/api/keys?databaseIdHash=${databaseIdHash}`, { headers: { "Authorization": "Bearer <YOUR_API_KEY>", "database-id-hash": databaseIdHash } } ); if (!response.ok) { throw new Error(`Error listing keys: ${response.statusText}`); } return await response.json();}
// UsagelistKeys("35f5c5b139a6b569d4649b7...") .then((data) => console.log("All keys:", data)) .catch(console.error);
3.1.4 Example Response (HTTP 200)
[ { "displayName": "My Key #1", "keyLocatorHash": "1122334455667788aaabbbcccdddeeefff0011223344556677aaabbbcccdddee", "keyHash": "abc1234def5678...", "databaseIdHash": "35f5c5b139a6b569d4649b7...", "encryptedMasterKey": "base64-or-other-encrypted-string", "acl": null, "extra": null, "expiryDate": null, "updatedAt": "2025-03-21T11:00:00.000Z" }, ...]
Using the TypeScript API Client
import { OpenAgentsBuilderClient } from "open-agents-builder-client";
const client = new OpenAgentsBuilderClient({ apiKey: "<YOUR_API_KEY>", databaseIdHash: "<YOUR_DATABASE_ID_HASH>"});
async function listKeysClientExample() { const keys = await client.keys.listKeys({ databaseIdHash: "35f5c5b139a6b569d4649b7..." }); console.log("Keys (via client):", keys);}
listKeysClientExample();
3.2 PUT /api/keys
3.2.1 Description
Upserts a key by keyLocatorHash
. If none exists, it creates a new one; otherwise it updates. Requires owner role.
Important: For details on how keys are created in the broader system, please refer to the relevant code in the Key Context (GitHub). This shows how keyHash
, keyLocatorHash
, and other fields might be derived or generated in practice.
3.2.2 Request Body
Must match KeyDTO
, for example:
{ "displayName": "My Key #1", "keyLocatorHash": "1122334455667788aaabbbcccdddeeefff0011223344556677aaabbbcccdddee", "keyHash": "abc123def456...", "keyHashParams": "some-params", "databaseIdHash": "35f5c5b139a6b569d4649b7...", "encryptedMasterKey": "some-encrypted-value", "acl": "{\"role\":\"owner\"}"}
3.2.3 cURL Example
curl -X PUT \ "https://app.openagentsbuilder.com/api/keys" \ -H "Authorization: Bearer <YOUR_API_KEY>" \ -H "database-id-hash: 35f5c5b139a6b5..." \ -H "Content-Type: application/json" \ -d '{ "displayName": "My Key #1", "keyLocatorHash": "1122334455667788aaabbbcccdddeeefff0011223344556677aaabbbcccdddee", "keyHash": "abc123def456...", "keyHashParams": "some-params", "databaseIdHash": "35f5c5b139a6b569d4649b7...", "encryptedMasterKey": "some-encrypted-value" }'
3.2.4 TypeScript (fetch) Example
async function upsertKey(keyData: any) { const response = await fetch("https://app.openagentsbuilder.com/api/keys", { method: "PUT", headers: { "Authorization": "Bearer <YOUR_API_KEY>", "database-id-hash": "<YOUR_DATABASE_ID_HASH>", "Content-Type": "application/json" }, body: JSON.stringify(keyData) });
const result = await response.json(); if (!response.ok) { throw new Error(`Error upserting key: ${result.message}`); } console.log("Upserted key:", result); return result;}
// Usage:upsertKey({ displayName: "My Key #1", keyLocatorHash: "1122334455667788aaabbbcccdddeeefff0011223344556677aaabbbcccdddee", keyHash: "abc123def456...", keyHashParams: "some-params", databaseIdHash: "35f5c5b139a6b569d4649b7...", encryptedMasterKey: "some-encrypted-value"}).catch(console.error);
3.2.5 Example Success Response (HTTP 200)
{ "message": "Data saved successfully!", "data": { "displayName": "My Key #1", "keyLocatorHash": "1122334455667788aaabbbcccdddeeefff0011223344556677aaabbbcccdddee", "keyHash": "abc123def456...", "keyHashParams": "some-params", "databaseIdHash": "35f5c5b139a6b569d4649b7...", "encryptedMasterKey": "some-encrypted-value", "acl": null, "extra": null, "expiryDate": null, "updatedAt": "2025-03-21T11:00:00.000Z" }, "status": 200}
Using the TypeScript API Client
import { OpenAgentsBuilderClient } from "open-agents-builder-client";
const client = new OpenAgentsBuilderClient({ apiKey: "<YOUR_API_KEY>", databaseIdHash: "<YOUR_DATABASE_ID_HASH>"});
async function upsertKeyClientExample() { const keyData = { displayName: "My Key #1", keyLocatorHash: "1122334455667788aaabbbcccdddeeefff0011223344556677aaabbbcccdddee", keyHash: "abc123def456...", keyHashParams: "some-params", databaseIdHash: "35f5c5b139a6b569d4649b7...", encryptedMasterKey: "some-encrypted-value" }; const result = await client.keys.upsertKey(keyData); console.log("Upserted key via client:", result);}
upsertKeyClientExample();
3.3 DELETE /api/keys/[key]
3.3.1 Description
Deletes the key whose keyLocatorHash
equals [key]
. Also requires owner role.
3.3.2 cURL Example
curl -X DELETE \ "https://app.openagentsbuilder.com/api/keys/1122334455667788aaabbbcccdddeeefff0011223344556677aaabbbcccdddee" \ -H "Authorization: Bearer <YOUR_API_KEY>" \ -H "database-id-hash: 35f5c5b139a6b5..."
3.3.3 TypeScript (fetch) Example
async function deleteKey(keyLocatorHash: string) { const response = await fetch( `https://app.openagentsbuilder.com/api/keys/${keyLocatorHash}`, { method: "DELETE", headers: { "Authorization": "Bearer <YOUR_API_KEY>", "database-id-hash": "<YOUR_DATABASE_ID_HASH>" } } ); const result = await response.json(); if (!response.ok) { throw new Error(`Error deleting key: ${result.message}`); } console.log("Delete result:", result); return result;}
// Usage:deleteKey("1122334455667788aaabbbcccdddeeefff0011223344556677aaabbbcccdddee") .catch(console.error);
3.3.4 Example Success Response (HTTP 200)
{ "message": "Data deleted successfully!", "status": 200}
If not found:
{ "message": "Data not found!", "status": 400 }
Using the TypeScript API Client
async function deleteKeyClientExample() { const keyLocatorHash = "1122334455667788aaabbbcccdddeeefff0011223344556677aaabbbcccdddee"; const deleted = await client.keys.deleteKey(keyLocatorHash); console.log("Deleted key via client:", deleted);}
deleteKeyClientExample();
4. Authorization & Roles
Only an owner
role can create, update, or delete keys:
if (requestContext.acl.role !== 'owner') { return Response.json({ message: "Owner role is required", status: 401 }, { status: 401});}
If the user is not owner
, the endpoints return 401 Unauthorized
.
5. Error Handling
- 400: Missing or invalid input (e.g.,
keyLocatorHash
must be 64 chars). - 401: If your ACL role is not
owner
forPUT
/DELETE
. - 404 or 400: If the key does not exist on delete.
- 499/500: Server or DB issues.
Error responses generally have:
{ "message": "Error details", "status": <number>}
6. Important Note on Key Creation
When creating a key (via PUT /api/keys
), please refer to the key creation logic in the Key Context code on GitHub. That code shows how the fields (keyHash
, keyLocatorHash
, encryptedMasterKey
, etc.) might be derived or generated in a broader context. Understanding that logic ensures your new keys are correctly formed.
7. Summary of Keys Endpoints
Endpoint | Method | Requires | Purpose |
---|---|---|---|
/api/keys | GET | Valid bearer & DB hash | List keys; filters by databaseIdHash , keyLocatorHash , keyHash . |
/api/keys | PUT | role === 'owner' | Upsert a key by keyLocatorHash . Requires reading the Key Context logic. |
/api/keys/[key] | DELETE | role === 'owner' | Delete a key record by keyLocatorHash . |
That’s the full Keys API reference. Remember to check the Key Context creation logic to properly form your key data before calling these endpoints!