Skip to main content

Overview

TinybirdApi is a low-level API wrapper that provides direct access to Tinybird’s REST API. It is intentionally decoupled from the typed TinybirdClient layer, allowing you to use it standalone with just a baseUrl and token. This class is useful when you need:
  • Direct API access without type definitions
  • Dynamic queries without compile-time type checking
  • A lightweight wrapper for scripting or automation
  • To integrate Tinybird into existing codebases without adopting the full SDK

Constructor

The TinybirdApi class is typically created using the createTinybirdApi() function:
import { createTinybirdApi } from "@tinybirdco/sdk";

const api = createTinybirdApi({
  baseUrl: "https://api.tinybird.co",
  token: process.env.TINYBIRD_TOKEN!,
});

Methods

query()

Query a Tinybird API endpoint (pipe) with optional parameters.
query<T = unknown, P extends Record<string, unknown> = Record<string, unknown>>(
  endpointName: string,
  params?: P,
  options?: TinybirdApiQueryOptions
): Promise<QueryResult<T>>

Parameters

endpointName
string
required
The name of the pipe endpoint to query
params
Record<string, unknown>
Query parameters to pass to the endpoint. Array values are sent as multiple query parameters with the same key.
options
TinybirdApiQueryOptions
Additional options:
  • token: Optional token override for this request
  • timeout: Request timeout in milliseconds
  • signal: AbortSignal for cancellation

Example

interface TopPagesRow { pathname: string; visits: number }
interface TopPagesParams { start_date: string; end_date: string; limit?: number }

const result = await api.query<TopPagesRow, TopPagesParams>("top_pages", {
  start_date: "2024-01-01",
  end_date: "2024-01-31",
  limit: 5,
});

console.log(result.data); // Array of TopPagesRow
Important: Do not pass Date objects as query parameters. Use strings in formats like YYYY-MM-DD or YYYY-MM-DD HH:MM:SS instead.

ingest()

Ingest a single row of data into a datasource.
ingest<T extends Record<string, unknown>>(
  datasourceName: string,
  event: T,
  options?: TinybirdApiIngestOptions
): Promise<IngestResult>

Parameters

datasourceName
string
required
The name of the datasource to ingest data into
event
Record<string, unknown>
required
The row data to ingest. Must match your datasource schema.
options
TinybirdApiIngestOptions
Additional options:
  • token: Optional token override for this request
  • wait: Whether to wait for data to be committed (default: true)
  • timeout: Request timeout in milliseconds
  • signal: AbortSignal for cancellation

Example

interface EventRow {
  timestamp: string;
  event_name: string;
  pathname: string;
}

await api.ingest<EventRow>("events", {
  timestamp: "2024-01-15 10:30:00",
  event_name: "page_view",
  pathname: "/home",
});
Important: Do not pass Date objects in the event payload. Use strings in formats like YYYY-MM-DD HH:MM:SS instead.

ingestBatch()

Ingest multiple rows of data into a datasource in a single request.
ingestBatch<T extends Record<string, unknown>>(
  datasourceName: string,
  events: T[],
  options?: TinybirdApiIngestOptions
): Promise<IngestResult>

Parameters

datasourceName
string
required
The name of the datasource to ingest data into
events
Array<Record<string, unknown>>
required
Array of row data to ingest. Each row must match your datasource schema.
options
TinybirdApiIngestOptions
Same options as ingest()

Example

await api.ingestBatch("events", [
  { timestamp: "2024-01-15 10:30:00", event_name: "page_view", pathname: "/home" },
  { timestamp: "2024-01-15 10:31:00", event_name: "click", pathname: "/pricing" },
]);

sql()

Execute raw SQL queries against Tinybird.
sql<T = unknown>(
  sql: string,
  options?: TinybirdApiQueryOptions
): Promise<QueryResult<T>>

Parameters

sql
string
required
The SQL query to execute
options
TinybirdApiQueryOptions
Additional options:
  • token: Optional token override for this request
  • timeout: Request timeout in milliseconds
  • signal: AbortSignal for cancellation

Example

interface CountResult { total: number }

const result = await api.sql<CountResult>("SELECT count() AS total FROM events");
console.log(result.data[0].total);

appendDatasource()

Append data to a datasource from a remote URL or local file.
appendDatasource(
  datasourceName: string,
  options: AppendOptions,
  apiOptions?: TinybirdApiAppendOptions
): Promise<AppendResult>

Parameters

datasourceName
string
required
The name of the datasource to append data to
options
AppendOptions
required
Source options:
  • url: Remote URL to a CSV, NDJSON, or Parquet file (mutually exclusive with file)
  • file: Local file path (mutually exclusive with url)
  • csvDialect: Optional CSV parsing options (delimiter, newLine, escapeChar)
  • timeout: Request timeout in milliseconds
  • signal: AbortSignal for cancellation
apiOptions
TinybirdApiAppendOptions
Additional options:
  • mode: "append" (default) or "replace" to replace all existing data
  • token: Optional token override for this request

Example

// Import from remote URL
await api.appendDatasource("events", {
  url: "https://example.com/events.csv",
});

// Replace all data
await api.appendDatasource(
  "events",
  { url: "https://example.com/events.csv" },
  { mode: "replace" }
);
The format (CSV, NDJSON, Parquet) is automatically detected from the file extension.

deleteDatasource()

Delete rows from a datasource that match a SQL condition.
deleteDatasource(
  datasourceName: string,
  options: DeleteOptions,
  apiOptions?: TinybirdApiDeleteOptions
): Promise<DeleteResult>

Parameters

datasourceName
string
required
The name of the datasource to delete rows from
options
DeleteOptions
required
Delete options:
  • deleteCondition: SQL WHERE clause to match rows (required)
  • dryRun: Preview deletion without executing (optional)
  • timeout: Request timeout in milliseconds
  • signal: AbortSignal for cancellation
apiOptions
TinybirdApiDeleteOptions
Additional options:
  • token: Optional token override for this request

Example

// Delete matching rows
await api.deleteDatasource("events", {
  deleteCondition: "event_name = 'test'",
});

// Dry run to preview what would be deleted
const preview = await api.deleteDatasource("events", {
  deleteCondition: "event_name = 'test'",
  dryRun: true,
});
console.log(`Would delete ${preview.rows_to_be_deleted} rows`);
Be careful with delete operations. Always test with dryRun: true first to verify the condition matches the expected rows.

truncateDatasource()

Remove all rows from a datasource.
truncateDatasource(
  datasourceName: string,
  options?: TruncateOptions,
  apiOptions?: TinybirdApiTruncateOptions
): Promise<TruncateResult>

Parameters

datasourceName
string
required
The name of the datasource to truncate
options
TruncateOptions
  • timeout: Request timeout in milliseconds
  • signal: AbortSignal for cancellation
apiOptions
TinybirdApiTruncateOptions
Additional options:
  • token: Optional token override for this request

Example

// Remove all rows from the datasource
await api.truncateDatasource("events");
Truncate permanently removes all data. This operation cannot be undone.

createToken()

Create a scoped token using the Tinybird Token API. Supports both static tokens and JWT tokens.
createToken(
  body: TinybirdApiCreateTokenRequest,
  options?: TinybirdApiCreateTokenOptions
): Promise<TinybirdApiCreateTokenResult>

Parameters

body
TinybirdApiCreateTokenRequest
required
Token configuration:
  • name: Token name/identifier
  • scopes: JWT-style scope objects (array of { type, resource?, fixed_params?, filter? })
  • scope: Static-token scope strings (string or string array)
  • limits: Optional rate-limiting config ({ rps?: number })
options
TinybirdApiCreateTokenOptions
Additional options:
  • expirationTime: Optional expiration time for JWT tokens (Unix timestamp)
  • token: Optional token override for this request
  • timeout: Request timeout in milliseconds
  • signal: AbortSignal for cancellation

Example

const { token } = await api.createToken({
  name: "user_123_session",
  scopes: [
    {
      type: "PIPES:READ",
      resource: "user_dashboard",
      fixed_params: { user_id: 123 },
    },
  ],
  limits: { rps: 10 },
});

request()

Execute a low-level HTTP request against the Tinybird API.
request(
  path: string,
  init?: TinybirdApiRequestInit
): Promise<Response>

Parameters

path
string
required
The API path (e.g., /v1/workspace)
init
TinybirdApiRequestInit
Standard RequestInit options plus:
  • token: Optional token override for this request

Example

const response = await api.request("/v1/workspace");
const data = await response.json();

requestJson()

Execute a request and automatically parse the JSON response.
requestJson<T = unknown>(
  path: string,
  init?: TinybirdApiRequestInit
): Promise<T>

Parameters

path
string
required
The API path (e.g., /v1/workspace)
init
TinybirdApiRequestInit
Standard RequestInit options plus:
  • token: Optional token override for this request

Example

interface Workspace { id: string; name: string }

const workspace = await api.requestJson<Workspace>("/v1/workspace");
console.log(workspace.name);

Error Handling

All methods throw TinybirdApiError when the API returns a non-OK response:
import { TinybirdApiError } from "@tinybirdco/sdk";

try {
  await api.query("broken_endpoint");
} catch (error) {
  if (error instanceof TinybirdApiError) {
    console.error(`API Error ${error.statusCode}: ${error.message}`);
    console.error(error.response); // Parsed error response from Tinybird
  }
}

Token Override

Most methods support per-request token override, useful for:
  • Multi-tenant applications with different tokens per user
  • Testing with different permission levels
  • Using branch-specific tokens
const api = createTinybirdApi({
  baseUrl: "https://api.tinybird.co",
  token: process.env.TINYBIRD_DEFAULT_TOKEN!,
});

// Use a different token for this request
await api.query(
  "top_pages",
  { start_date: "2024-01-01", end_date: "2024-01-31" },
  { token: process.env.TINYBIRD_BRANCH_TOKEN }
);

createTinybirdApi()

Factory function to create a TinybirdApi instance

Tinybird Client

Type-safe client with schema definitions

Build docs developers (and LLMs) love