Skip to main content

Overview

The HTTP Handler transform allows you to enrich streaming data by calling external HTTP endpoints. This is useful for:
  • Enriching blockchain data with off-chain information
  • Calling ML models for predictions or classifications
  • Integrating with third-party APIs for additional context
  • Custom business logic hosted in external services

Configuration

Parameters

string
required
Must be handler
string
required
The source or transform to read data from
string
required
The HTTP endpoint URL to call. Must be a fully-qualified URL (e.g., https://api.example.com/enrich). Requests are always sent as HTTP POST with a JSON body.
string
required
The column that uniquely identifies each row
string
The name of a Goldsky httpauth secret containing an authentication header to include with each request. Create one with goldsky secret create and select httpauth as the type.
object
Additional HTTP headers sent with every request, as a map of header name to value. Content-Type: application/json is set automatically if not provided. Headers from secret_name are merged in on top of this map.
boolean
default:"false"
  • true: Send each row individually as a single JSON object
  • false (default): Send multiple rows as a JSON array (batched, up to 2000 rows per request)
integer
default:"0"
Payload envelope version. 0 (default) sends raw row JSON. 1 wraps each row in {"metadata": {"op": "<i|u|d>"}, "data": {...}} so the receiver can distinguish inserts, updates, and deletes. Responses must match the same envelope version.
object
Map of column name to Arrow data type string used to reshape the output schema. Add a new column by mapping a new name to a type (e.g. risk_score: Float64), change a column’s type by mapping an existing name to a new type, or drop a column by mapping its name to null. Without this field, the output schema must match the input schema exactly.

Request Format

Single Row Mode (one_row_per_request: true)

When enabled, each row is sent as an individual HTTP POST request with JSON body:
Use when:
  • Your API doesn’t support batch processing
  • Each request requires significant processing time
  • You need real-time, row-by-row processing

Batch Mode (one_row_per_request: false)

When disabled, multiple rows are sent as a JSON array:
Batches contain up to 2000 rows per request. Larger input batches are split into multiple sequential HTTP requests. Use when:
  • Your API supports batch processing
  • You want to reduce network overhead
  • Higher throughput is needed

Response Format

Your HTTP endpoint must return JSON with the same structure as the input, plus any additional fields you want to add.

Single Row Response

Batch Response

By default, the response must include every column from the input schema with matching types, plus any new fields you want to add. To add, remove, or retype columns, declare them in schema_override.

Example: Enrich Transfers with Wallet Labels

Example API Implementation

Here’s a simple example of an HTTP endpoint that enriches wallet data:

Example: ML Model Integration

Call a machine learning model to classify transactions:
The ML endpoint might return:

Error Handling and Retries

The HTTP handler includes built-in retry logic:
  • Transient errors (network errors, request timeouts, 408, 429, and all 5xx responses): Retried indefinitely with exponential backoff. The pipeline blocks on the failing batch until the endpoint recovers.
  • Permanent errors (other 4xx responses, invalid JSON response): The pipeline fails immediately with no retries.
  • Request timeout: Each request has a 300-second timeout by default, configured globally and not tunable per-transform.
Ensure your endpoint can handle retries idempotently. The same request may be sent multiple times if there are transient failures.

Performance Considerations

HTTP handlers add latency to your pipeline:
  • Each request takes at least the network round-trip time
  • Plus your endpoint’s processing time
  • Use batching (one_row_per_request: false) to reduce overhead
  • Consider caching frequently requested data in your API
To maximize throughput:
  • Use batch mode when possible (10-100 rows per batch works well)
  • Ensure your API can handle concurrent requests
  • Scale your API horizontally if it becomes a bottleneck
  • Monitor API response times in your pipeline logs
If your HTTP endpoint is slow:
  • The entire pipeline will slow down to match
  • This prevents data loss and memory overflow
  • Scale your API or optimize its response time
  • Monitor logs for HTTP handler performance metrics

Security Best Practices

1

Use HTTPS

Always use HTTPS endpoints to encrypt data in transit:
2

Use secret_name for authentication

Use the secret_name parameter with an httpauth secret to securely authenticate with your endpoint. This avoids exposing credentials in your pipeline configuration:
Create the secret with goldsky secret create and select httpauth as the type.
3

Validate the authentication header

Verify the secret header in your endpoint:
4

Validate Input

Always validate incoming data in your endpoint:
5

Rate Limiting

Implement rate limiting to prevent abuse:

Limitations

HTTP Handler transforms have some limitations to be aware of:
  • Schema changes require schema_override: By default, the response schema must match the input. To add, remove, or retype columns, declare them explicitly in schema_override.
  • Response size: Very large responses (>10MB) may cause issues.
  • Timeout: Requests that exceed 300 seconds are canceled and retried as transient errors.
  • Order: In batch mode, responses must be returned in the same order as the input rows.
  • Retriable failures block the pipeline: The handler retries 5xx, 408, 429, and network errors forever, so a persistently failing endpoint will stall the pipeline rather than drop rows.

Debugging

View logs to debug HTTP handler issues:
Look for:
  • HTTP status codes (200 = success, 4xx/5xx = errors)
  • Response times
  • Retry attempts
  • Error messages from your endpoint
Common issues:
  • “Connection refused”: Your endpoint is not reachable
  • “Timeout”: Your endpoint is too slow — optimize it, or reduce the number of rows per batch by lowering row volume upstream
  • “Schema mismatch”: Response doesn’t include all original fields (or the extra fields need to be declared in schema_override)
  • “Invalid JSON”: Your endpoint returned malformed JSON

Best Practices

Only send rows that need enrichment to reduce API calls:
Batch mode reduces network overhead:
Aim for under 100ms response times:
  • Cache frequently accessed data
  • Use database indexes
  • Optimize expensive computations
  • Consider async processing for slow operations
Track metrics like:
  • Request rate
  • Response times (p50, p95, p99)
  • Error rates
  • Resource usage (CPU, memory)
Make your endpoint resilient:
  • Return partial results on partial failures
  • Log errors for debugging
  • Implement circuit breakers for downstream dependencies
  • Provide fallback values when enrichment fails