Skip to main content
Executes a raw SQL query directly against WorqDB. This endpoint provides direct SQL access with security guardrails to prevent destructive operations.
POST https://api.worqhat.com/db/query

What Does This Endpoint Do?

This endpoint allows you to execute SQL queries directly against your database. Think of it like having direct access to your database through SQL, but with safety measures in place to prevent accidental data loss or destructive operations. You can use both named parameters ({param}) and positional parameters ($1, $2) to safely pass values into your queries, preventing SQL injection attacks.

When to Use SQL Queries

You’ll find this endpoint useful when you need to:
  • Run complex queries: Perform advanced data analysis with SQL
  • Generate reports: Create custom reports with aggregations and calculations
  • Fetch specific data: Retrieve exactly what you need with precise SQL queries
  • Run analytical queries: Perform calculations and aggregations on your data
  • Use SQL functions: Leverage SQL’s built-in functions for data manipulation
  • Perform bulk operations: Execute operations on multiple records efficiently

How It Works

  1. You provide a SQL query to execute (with optional parameters)
  2. You can use named parameters ({param}) or positional parameters ($1, $2) for safe value substitution
  3. The API runs your query against the database with security guardrails
  4. The results are returned as an array of objects

Code Examples

Example 1: Basic SQL Query with Named Parameters

This example shows how to execute a simple SQL query using named parameters to safely pass values.
  • Node.js
  • Python
  • Go
  • cURL
import Worqhat from 'worqhat';

// Initialize the client with your API key
const client = new Worqhat({
  apiKey: process.env.WORQHAT_API_KEY, // Always use environment variables for API keys
});

async function fetchActiveUsers() {
  try {
    // Call the executeQuery method with named parameters
    const response = await client.db.executeQuery({
      query: "SELECT * FROM users WHERE status = {status} LIMIT {limit}",
      params: {
        status: "active",
        limit: 10
      },
      environment: process.env.WORQHAT_ENVIRONMENT || 'production' // Defaults to production
    });
    
    // Handle the successful response
    console.log(`Found ${response.data.length} active users`);
    console.log('Query execution time:', response.executionTime, 'ms');
    console.log('Results:', response.data);
    return response;
  } catch (error) {
    // Handle any errors
    console.error('Error executing query:', error.message);
  }
}

// Call the function
fetchActiveUsers();

Example 2: Advanced SQL Query with Positional Parameters

This example shows how to execute a more complex SQL query using positional parameters for safe value substitution.
  • Node.js
  • Python
  • Go
  • cURL
import Worqhat from 'worqhat';

// Initialize the client with your API key
const client = new Worqhat({
  apiKey: process.env.WORQHAT_API_KEY,
});

async function generateSalesReport() {
  try {
    // Complex SQL query with positional parameters
    const query = `
      SELECT 
        category, 
        COUNT(*) as order_count, 
        SUM(quantity) as total_items, 
        SUM(price * quantity) as total_revenue
      FROM orders
      WHERE order_date >= $1
      GROUP BY category
      ORDER BY total_revenue DESC
    `;
    
    // Execute the query with positional parameters
    const response = await client.db.executeQuery({ 
      query,
      params: ['2025-01-01'],
      environment: process.env.WORQHAT_ENVIRONMENT || 'production' // Defaults to production
    });
    
    // Handle the successful response
    console.log('Sales report generated successfully');
    console.log('Report data:', response.data);
    return response;
  } catch (error) {
    console.error('Error generating sales report:', error.message);
  }
}

generateSalesReport();

Example 3: Mixed Parameter Types

This example shows how to use both named and positional parameters in the same query for maximum flexibility.
  • Node.js
  • Python
  • cURL
import Worqhat from 'worqhat';

// Initialize the client with your API key
const client = new Worqhat({
  apiKey: process.env.WORQHAT_API_KEY,
});

async function searchUsers() {
  try {
    // Query using both parameter types
    const response = await client.db.executeQuery({
      query: "SELECT * FROM users WHERE status = {status} AND created_at >= $1 ORDER BY {sort_by} LIMIT $2",
      params: {
        status: "active",
        sort_by: "created_at"
      },
      environment: process.env.WORQHAT_ENVIRONMENT || 'production', // Defaults to production
      // Note: Positional parameters are passed as an array
      // The query will use $1 and $2 for the positional params
    });
    
    console.log('Search completed successfully');
    console.log('Results:', response.data);
    return response;
  } catch (error) {
    console.error('Error searching users:', error.message);
  }
}

searchUsers();

Request Body Explained

query
string
required
The SQL query to execute against the database. This can be any valid SQL query that reads data (SELECT statements).You can use either:
  • Named parameters: {param} syntax (e.g., SELECT * FROM users WHERE status = {status})
  • Positional parameters: $1, $2, $3 syntax (e.g., SELECT * FROM users WHERE status = $1)
For security reasons, certain operations may be restricted to prevent accidental data loss or unauthorized access.
params
object | array
Parameters to safely substitute into your SQL query. Choose one format:For named parameters ({param} syntax): Provide an object with key-value pairs.
{"status": "active", "limit": 10}
For positional parameters ($1, $2 syntax): Provide an array of values in order.
["active", 10]
environment
string
The environment to query (development, staging, production). Defaults to production if not specified.Options: development, staging, production

Response Fields Explained

success
boolean
true if the query was executed successfully, false otherwise.
data
array
An array of objects containing the query results. Each object represents a row in the result set, with properties corresponding to the columns in your query.
query
string
The SQL query that was executed. This is useful for debugging and audit purposes.
executionTime
integer
The time taken to execute the query in milliseconds. This can help you optimize slow queries.

Example Response

{
  "success": true,
  "data": [
    {
      "id": "user_123",
      "name": "John Doe",
      "email": "john@example.com",
      "status": "active"
    },
    {
      "id": "user_456",
      "name": "Jane Smith",
      "email": "jane@example.com",
      "status": "active"
    }
  ],
  "query": "SELECT * FROM users WHERE status = 'active' LIMIT 10",
  "executionTime": 42
}

Common Errors and How to Fix Them

ErrorCauseSolution
”Table not found”The specified table doesn’t existCheck your table name for typos
”Syntax error in SQL query”The SQL query contains syntax errorsReview your SQL syntax and fix any errors
”Operation not allowed”You’re trying to perform a restricted operationUse only allowed operations (typically SELECT statements)
“Query timeout”The query took too long to executeOptimize your query or add more specific conditions
”Unauthorized”Invalid or missing API keyCheck that you’re using a valid API key

Tips for Successful Queries

  • Use parameters for all dynamic values to prevent SQL injection attacks
  • Choose the right parameter type: Use named parameters for readability, positional for performance
  • Use LIMIT clauses to restrict the number of results returned
  • Be specific with your SELECT columns rather than using SELECT *
  • Add appropriate WHERE clauses to filter results
  • Use indexes when querying large tables
  • Test complex queries on small datasets first
  • Consider query performance for production applications

Parameter Safety

Both named ({param}) and positional ($1, $2) parameters provide protection against SQL injection by properly escaping values. Choose the approach that best fits your use case:
  • Named parameters: More readable and maintainable for complex queries
  • Positional parameters: Slightly more performant for simple queries with few parameters
  • Mixed usage: You can use both types in the same query for maximum flexibility