
Security News
Software Engineering Daily Podcast: Feross on AI, Open Source, and Supply Chain Risk
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.
@keboola/query-service
Advanced tools
TypeScript client for Keboola Query Service API.
npm install @keboola/query-service
# or
yarn add @keboola/query-service
# or
pnpm add @keboola/query-service
import { Client } from '@keboola/query-service';
// Initialize client
// IMPORTANT: Use query.keboola.com (NOT connection.keboola.com)
// Don't append /api/v1 - the SDK handles routing automatically
const client = new Client({
baseUrl: 'https://query.keboola.com', // Query Service URL
token: 'your-storage-api-token' // Your Keboola Storage API token
});
// Execute a query
const results = await client.executeQuery({
branchId: '1261313', // Your branch ID
workspaceId: '2950146661', // Your workspace ID
statements: ['SELECT * FROM my_table LIMIT 10']
});
// Process results - one QueryResult per statement
for (const result of results) {
console.log('Columns:', result.columns.map(col => col.name));
console.log('Data:', result.data);
}
import { Client } from '@keboola/query-service';
const client = new Client({
baseUrl: 'https://query.keboola.com',
token: process.env.KBC_TOKEN!
});
// Execute multiple statements transactionally
const results = await client.executeQuery({
branchId: '123',
workspaceId: '456',
statements: [
"SELECT * FROM orders WHERE date > '2024-01-01'",
"SELECT COUNT(*) FROM customers"
],
transactional: true // Execute in a transaction
});
// Results is an array - one QueryResult per statement
const ordersResult = results[0];
const countResult = results[1];
console.log(`Columns: ${ordersResult.columns.map(c => c.name)}`);
console.log(`Rows: ${ordersResult.data.length}`);
For more control, use the low-level methods:
// Submit job without waiting
const jobId = await client.submitJob({
branchId: '123',
workspaceId: '456',
statements: ['SELECT * FROM large_table']
});
// Check status
const status = await client.getJobStatus(jobId);
console.log(`Status: ${status.status}`); // created, enqueued, processing, completed, failed
// Wait for completion
const finalStatus = await client.waitForJob({
queryJobId: jobId,
maxWaitTime: 300000 // 5 minutes
});
// Get results for specific statement
const result = await client.getJobResults({
queryJobId: jobId,
statementId: finalStatus.statements[0].id
});
// Stream results as NDJSON for large datasets
for await (const row of client.streamResults(jobId, statementId)) {
processRow(row);
}
import {
Client,
AuthenticationError,
ValidationError,
JobError,
JobTimeoutError,
} from '@keboola/query-service';
try {
const results = await client.executeQuery({...});
} catch (error) {
if (error instanceof AuthenticationError) {
console.log('Invalid token');
} else if (error instanceof ValidationError) {
console.log(`Invalid request: ${error.message}`);
} else if (error instanceof JobError) {
console.log(`Query failed: ${error.message}`);
for (const stmt of error.failedStatements) {
console.log(` Statement ${stmt.id}: ${stmt.error}`);
}
} else if (error instanceof JobTimeoutError) {
console.log(`Job ${error.jobId} timed out`);
}
}
// app/api/query/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { Client, JobError } from '@keboola/query-service';
const client = new Client({
baseUrl: process.env.KEBOOLA_QUERY_URL!,
token: process.env.KEBOOLA_TOKEN!
});
export async function POST(request: NextRequest) {
const { sql } = await request.json();
try {
const results = await client.executeQuery({
branchId: process.env.KEBOOLA_BRANCH_ID!,
workspaceId: process.env.KEBOOLA_WORKSPACE_ID!,
statements: [sql]
});
return NextResponse.json({
columns: results[0].columns,
data: results[0].data
});
} catch (error) {
if (error instanceof JobError) {
return NextResponse.json({ error: error.message }, { status: 400 });
}
throw error;
}
}
const history = await client.getQueryHistory({
branchId: '123',
workspaceId: '456',
pageSize: 100
});
for (const stmt of history.statements) {
console.log(`${stmt.queryJobId}: ${stmt.query.slice(0, 50)}... (${stmt.status})`);
}
const client = new Client({
baseUrl: 'https://query.keboola.com',
token: 'your-token',
timeout: 120000, // Request timeout (ms)
maxRetries: 3, // Max retry attempts
userAgent: 'my-app/1.0' // Custom user agent
});
| Method | Description |
|---|---|
executeQuery() | Submit query, wait for completion, return results |
submitJob() | Submit query job without waiting |
getJobStatus() | Get current job status |
getJobResults() | Get results for a statement |
waitForJob() | Wait for job to complete |
cancelJob() | Cancel a running job |
getQueryHistory() | Get query history for workspace |
streamResults() | Stream results as NDJSON |
JobStatus - Job status with statementsQueryResult - Query results with columns and dataStatement - Individual SQL statement infoColumn - Column metadataJobState - 'created' | 'enqueued' | 'processing' | 'completed' | 'failed' | 'canceled'StatementState - 'waiting' | 'processing' | 'completed' | 'failed' | 'canceled' | 'notExecuted'QueryServiceError - Base error classAuthenticationError - Invalid token (401)ValidationError - Invalid request (400)NotFoundError - Resource not found (404)JobError - Query execution failedJobTimeoutError - Job didn't complete in timeMIT
FAQs
TypeScript SDK for Keboola Query Service API
We found that @keboola/query-service demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.

Security News
GitHub has revoked npm classic tokens for publishing; maintainers must migrate, but OpenJS warns OIDC trusted publishing still has risky gaps for critical projects.

Security News
Rust’s crates.io team is advancing an RFC to add a Security tab that surfaces RustSec vulnerability and unsoundness advisories directly on crate pages.