SDK
Official TypeScript/JavaScript SDK for AnyDB. Provides a type-safe way to interact with the AnyDB API to manage records, databases, teams, and files programmatically.
Installation
npm install anydb-api-sdk-ts
Getting Your API Key
Before using the SDK, you'll need to obtain your API key:
- Log in to your AnyDB account at app.anydb.com
- Click on the user icon in the bottom right corner
- Navigate to the Integration tab in the Profile Dialog
- Copy your API key
Keep your API key secure. Never commit it to version control or share it publicly.
Quick Start
import { AnyDBClient } from "anydb-api-sdk-ts";
// Initialize the client
const client = new AnyDBClient({
apiKey: "your-api-key",
userEmail: "user@example.com",
baseURL: "https://app.anydb.com/api", // Optional
});
// List teams
const teams = await client.listTeams();
console.log("Teams:", teams);
// Get a record
const record = await client.getRecord("teamid", "adbid", "adoid");
console.log("Record:", record);
Features
✅ Full TypeScript support with type definitions
✅ Record operations - CRUD operations for AnyDB records
✅ File management - Upload and download files from record cells
✅ Team & database discovery - List teams and databases
✅ Search functionality - Search records by keyword
✅ Error handling - Comprehensive error messages
✅ Debug mode - Optional request/response logging
Client Configuration
Initialize the Client
const client = new AnyDBClient({
apiKey: string, // Required: Your AnyDB API key
userEmail: string, // Required: User email for authentication
baseURL: string, // Optional: API base URL (default: http://localhost:3000/api)
timeout: number, // Optional: Request timeout in ms (default: 30000)
});
Debug Mode
Enable debug logging to see all API requests and responses:
DEBUG_ANYDB=1 node your-script.js
API Reference
Team & Database Operations
List Teams
Get all teams accessible with your credentials.
const teams = await client.listTeams();
// Returns: Team[]
Response:
[
{
teamid: "507f1f77bcf86cd799439011",
name: "My Team",
description: "Team description",
},
];
List Databases for Team
Get all databases within a team.
const databases = await client.listDatabasesForTeam("teamid");
// Returns: ADB[]
Response:
[
{
adbid: "507f1f77bcf86cd799439012",
name: "My Database",
teamid: "507f1f77bcf86cd799439011",
},
];
Record Operations
List Records
List all records in a database with optional filtering and pagination.
const response = await client.listRecords(
"teamid",
"adbid",
"parentid", // Optional: Filter by parent record
"templateid", // Optional: Filter by template
"templatename", // Optional: Filter by template name
"50", // Optional: Page size (default: 50)
"lastmarker" // Optional: Pagination marker from previous response
);
console.log(response.items); // Array of records
console.log(response.total); // Total count
console.log(response.hasmore); // Has more pages
console.log(response.lastmarker); // Marker for next page
Example - Paginated List:
// Get first page
const page1 = await client.listRecords("teamid", "adbid");
// Get next page using lastmarker
if (page1.hasmore) {
const page2 = await client.listRecords(
"teamid",
"adbid",
undefined,
undefined,
undefined,
"50",
page1.lastmarker
);
}
Get Record
Get a specific record with all its data.
const record = await client.getRecord("teamid", "adbid", "adoid");
// Returns: ADORecord
Response:
{
meta: {
adoid: "507f1f77bcf86cd799439013",
adbid: "507f1f77bcf86cd799439012",
teamid: "507f1f77bcf86cd799439011",
name: "Record Name",
description: "Record description",
createdat: "2024-01-01T00:00:00.000Z",
updatedat: "2024-01-01T00:00:00.000Z"
},
content: {
A1: {
pos: "A1",
key: "firstName",
type: "string",
value: "John",
colspan: 1,
rowspan: 1
}
}
}
Create Record
Create a new record in a database.
import { ADOCellValueType } from "anydb-api-sdk-ts";
const newRecord = await client.createRecord({
teamid: "teamid",
adbid: "adbid",
name: "New Record",
description: "Optional description",
attach: "parentAdoid", // Optional: Attach to parent record
template: "templateid", // Optional: Use a template
content: {
A1: {
pos: "A1",
key: "firstName",
type: ADOCellValueType.STRING,
value: "John",
colspan: 1,
rowspan: 1,
},
B1: {
pos: "B1",
key: "age",
type: ADOCellValueType.NUMBER,
value: 30,
colspan: 1,
rowspan: 1,
},
},
});
// Returns: ADORecord
Predefined Templates:
import { PredefinedTemplateAdoIds } from "anydb-api-sdk-ts";
// Create a folder
const folder = await client.createRecord({
teamid,
adbid,
name: "My Folder",
template: PredefinedTemplateAdoIds.FOLDER_TEMPLATE_ADOID,
});
// Create a page
const page = await client.createRecord({
teamid,
adbid,
name: "My Page",
template: PredefinedTemplateAdoIds.PAGE_TEMPLATE_ADOID,
});
// Available templates:
// - FILE_TEMPLATE_ADOID
// - FOLDER_TEMPLATE_ADOID
// - PAGE_TEMPLATE_ADOID
// - LINK_TEMPLATE_ADOID
// - VIEW_TEMPLATE_ADOID
Update Record
Update an existing record.
const updatedRecord = await client.updateRecord({
meta: {
adoid: "adoid",
adbid: "adbid",
teamid: "teamid",
name: "Updated Name",
description: "New description",
},
content: {
A1: { value: "Updated value" },
B1: { value: 25 },
},
});
// Returns: ADORecord
Remove Record
Remove or delete a record.
import { NULL_OBJECTID } from "anydb-api-sdk-ts";
// Option 1: Remove from specific parent(s) (detach)
await client.removeRecord({
adoid: "adoid",
adbid: "adbid",
teamid: "teamid",
removefromids: "parentAdoid1,parentAdoid2", // Comma-separated parent IDs
});
// Option 2: Delete completely
await client.removeRecord({
adoid: "adoid",
adbid: "adbid",
teamid: "teamid",
removefromids: NULL_OBJECTID, // Special constant for complete deletion
});
// Returns: boolean (true on success)
Search Records
Search for records by keyword.
const results = await client.searchRecords({
teamid: "teamid",
adbid: "adbid",
search: "keyword",
limit: "10",
});
// Returns: ADORecord[]
Copy Record
Copy an existing record with optional attachment handling.
// Copy with no attachments
const copiedRecord = await client.copyRecord({
adoid: "sourceRecordId",
adbid: "adbid",
teamid: "teamid",
attachmentsmode: "noattachments", // Don't copy attachments
});
// Copy and link attachments
const copiedRecord = await client.copyRecord({
adoid: "sourceRecordId",
adbid: "adbid",
teamid: "teamid",
attachmentsmode: "link", // Link to original attachments
});
// Deep copy with attachments
const copiedRecord = await client.copyRecord({
adoid: "sourceRecordId",
adbid: "adbid",
teamid: "teamid",
attachmentsmode: "duplicate", // Duplicate all attachments
});
// Copy and attach to another record (e.g., a folder)
const copiedRecord = await client.copyRecord({
adoid: "sourceRecordId",
adbid: "adbid",
teamid: "teamid",
attachto: "targetParentId", // Attach copy to this record
attachmentsmode: "duplicate",
});
// Returns: ADORecord (the copied record)
Parameters:
adoid- ID of the record to copyadbid- Database IDteamid- Team IDattachto- Optional: ID of another record to attach the copy toattachmentsmode- Optional: How to handle attachments"noattachments"- Don't copy attachments"link"- Link to the original record's attachments"duplicate"- Create new copies of all attachments
Move Record
Move a record to a different parent folder.
const movedRecord = await client.moveRecord({
adoid: "recordId",
adbid: "adbid",
teamid: "teamid",
parentid: "newParentId", // New parent record ID
});
// Returns: ADORecord (the updated record)
Parameters:
adoid- ID of the record to moveadbid- Database IDteamid- Team IDparentid- ID of the new parent record
moveRecord is a convenience method that uses updateRecord internally to change the record's parent attachment.
File Operations
Download File
Download a file or get its download URL.
// Get download URL
const { url } = await client.downloadFile({
teamid: "teamid",
adbid: "adbid",
adoid: "adoid",
cellpos: "A1",
redirect: false, // Return URL instead of redirecting
preview: false, // Download instead of preview
});
console.log("Download URL:", url);
Parameters:
teamid- Team IDadbid- Database IDadoid- Record ID (file record)cellpos- Cell position where file is storedredirect- If true, returns redirect response; if false, returns URLpreview- If true, returns preview URL; if false, returns download URL
Upload File
Upload a file in one call. This automatically creates a child file record and handles the complete upload workflow.
// Upload from file content (Buffer or string)
const fileAdoid = await client.uploadFile({
filename: "document.pdf",
fileContent: fileBuffer, // Buffer or string
teamid: "teamid",
adbid: "adbid",
adoid: "parentAdoid", // Parent record to attach file to
cellpos: "A1", // Optional, defaults to "A1"
contentType: "application/pdf", // Optional MIME type
});
// Upload from file path
const fileAdoid = await client.uploadFile({
filename: "document.pdf",
filepath: "/path/to/document.pdf",
teamid: "teamid",
adbid: "adbid",
adoid: "parentAdoid",
cellpos: "A1",
});
console.log("File uploaded with ID:", fileAdoid);
// Returns: string (ADOID of the created file record)
The uploadFile method automatically:
- Creates a new file record as a child of the specified parent
- Gets an upload URL from AnyDB
- Uploads the file content to cloud storage
- Completes the upload process
Advanced Upload (Step-by-Step)
For more control, you can use the individual upload methods:
// Step 1: Get upload URL
const uploadUrl = await client.getUploadUrl({
filename: "document.pdf",
teamid: "teamid",
adbid: "adbid",
adoid: "adoid",
filesize: "1024",
cellpos: "A1",
});
// Step 2: Upload file to URL
await client.uploadFileToUrl(uploadUrl, fileBuffer, "application/pdf");
// Step 3: Complete upload
await client.completeUpload({
filesize: "1024",
teamid: "teamid",
adbid: "adbid",
adoid: "adoid",
cellpos: "A1",
});
Understanding AnyDB Concepts
IDs
- teamid - MongoDB ObjectId identifying a team/organization. Each team is a separate workspace
- adbid - MongoDB ObjectId for an ADB (AnyDB Database). Similar to a spreadsheet or table
- adoid - MongoDB ObjectId for an ADO (AnyDB Object/Record). Similar to a row in a spreadsheet
Cell Positions
Cell positions follow a grid system similar to spreadsheets:
- Valid format:
A1toA9,B1toB9,C1toC9, etc. - Invalid:
A0,B0, etc. (0 is not a valid row number)
Record Hierarchy
Records can have parent-child relationships:
- Use
attachparameter when creating records to attach to a parent - Use
parentidparameter when listing records to filter by parent - Files are typically child records attached to their parent records
Complete Example
Here's a complete workflow example:
import { AnyDBClient, ADOCellValueType } from "anydb-api-sdk-ts";
async function main() {
// Initialize client
const client = new AnyDBClient({
apiKey: process.env.ANYDB_API_KEY!,
userEmail: process.env.ANYDB_USER_EMAIL!,
baseURL: "https://app.anydb.com/api",
});
// 1. List teams
const teams = await client.listTeams();
const teamid = teams[0].teamid;
console.log(`Using team: ${teams[0].name}`);
// 2. List databases
const databases = await client.listDatabasesForTeam(teamid);
const adbid = databases[0].adbid;
console.log(`Using database: ${databases[0].name}`);
// 3. Create a new record
const record = await client.createRecord({
teamid,
adbid,
name: "Customer Record",
content: {
A1: {
pos: "A1",
key: "companyName",
type: ADOCellValueType.STRING,
value: "Acme Corp",
colspan: 1,
rowspan: 1,
},
B1: {
pos: "B1",
key: "employees",
type: ADOCellValueType.NUMBER,
value: 50,
colspan: 1,
rowspan: 1,
},
},
});
console.log("Created record:", record.meta.adoid);
// 4. Upload a file to the record
const fileBuffer = Buffer.from("Contract details...");
const fileAdoid = await client.uploadFile({
filename: "contract.txt",
fileContent: fileBuffer,
teamid,
adbid,
adoid: record.meta.adoid,
contentType: "text/plain",
});
console.log("File uploaded:", fileAdoid);
// 5. Search for records
const searchResults = await client.searchRecords({
teamid,
adbid,
search: "Acme",
limit: "10",
});
console.log(`Found ${searchResults.length} records`);
// 6. Update the record
const updated = await client.updateRecord({
meta: {
adoid: record.meta.adoid,
adbid,
teamid,
name: "Customer Record - Updated",
},
content: {
B1: { value: 75 }, // Update employee count
},
});
console.log("Record updated");
// 7. List child records (including the uploaded file)
const children = await client.listRecords(
teamid,
adbid,
record.meta.adoid // Filter by parent
);
console.log(`Record has ${children.items.length} children`);
}
main().catch(console.error);
Error Handling
The SDK throws descriptive errors with HTTP status codes:
try {
const record = await client.getRecord("teamid", "adbid", "invalid-adoid");
} catch (error) {
console.error(error.message);
// Example: "AnyDB API Error (404): Record not found"
}
Common Error Scenarios:
- 401 Unauthorized - Invalid API key or email
- 404 Not Found - Record, database, or team doesn't exist
- 400 Bad Request - Invalid parameters or malformed request
- 500 Server Error - Server-side error
TypeScript Support
The SDK is written in TypeScript and exports all types:
import type {
ADORecord,
Team,
ADB,
CreateRecordParams,
UpdateRecordParams,
RemoveRecordParams,
ListRecordsResponse,
SearchRecordsParams,
DownloadFileParams,
GetUploadUrlParams,
CompleteUploadParams,
ADOCellValueType,
} from "anydb-api-sdk-ts";
Best Practices
Secure API Keys
Store API keys in environment variables:
// .env file
ANYDB_API_KEY=your-api-key-here
ANYDB_USER_EMAIL=user@example.com
// In your code
import { AnyDBClient } from "anydb-api-sdk-ts";
import * as dotenv from "dotenv";
dotenv.config();
const client = new AnyDBClient({
apiKey: process.env.ANYDB_API_KEY!,
userEmail: process.env.ANYDB_USER_EMAIL!
});
Handle Pagination
Always handle pagination when listing records:
async function getAllRecords(client, teamid, adbid) {
const allRecords = [];
let lastmarker = undefined;
let hasmore = true;
while (hasmore) {
const response = await client.listRecords(
teamid,
adbid,
undefined,
undefined,
undefined,
"100", // Fetch 100 at a time
lastmarker
);
allRecords.push(...response.items);
lastmarker = response.lastmarker;
hasmore = response.hasmore;
}
return allRecords;
}
Use Templates
Leverage predefined templates for consistent record structure:
import { PredefinedTemplateAdoIds } from "anydb-api-sdk-ts";
// Create folder structure
const folder = await client.createRecord({
teamid,
adbid,
name: "Documents",
template: PredefinedTemplateAdoIds.FOLDER_TEMPLATE_ADOID,
});
// Create page inside folder
const page = await client.createRecord({
teamid,
adbid,
name: "Meeting Notes",
attach: folder.meta.adoid,
template: PredefinedTemplateAdoIds.PAGE_TEMPLATE_ADOID,
});
Resources
- npm Package: anydb-api-sdk-ts
- GitHub Repository: HumanlyInc/anydb-api-sdk-ts
- API Documentation: AnyDB API Docs
- Support: support@anydb.com
License
MIT License - See LICENSE for details.