cURL
curl --request POST \
--url https://app.indexing.co/dw/pipelines \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"name": "<string>",
"transformation": "<string>",
"filter": "<string>",
"filterKeys": [
"<string>"
],
"networks": [
"<string>"
],
"delivery": {
"adapter": "<string>",
"connection": "<string>",
"connectionUri": "<string>",
"table": "<string>",
"uniqueKeys": [
"<string>"
]
},
"enabled": true
}
'import requests
url = "https://app.indexing.co/dw/pipelines"
payload = {
"name": "<string>",
"transformation": "<string>",
"filter": "<string>",
"filterKeys": ["<string>"],
"networks": ["<string>"],
"delivery": {
"adapter": "<string>",
"connection": "<string>",
"connectionUri": "<string>",
"table": "<string>",
"uniqueKeys": ["<string>"]
},
"enabled": True
}
headers = {
"X-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
transformation: '<string>',
filter: '<string>',
filterKeys: ['<string>'],
networks: ['<string>'],
delivery: {
adapter: '<string>',
connection: '<string>',
connectionUri: '<string>',
table: '<string>',
uniqueKeys: ['<string>']
},
enabled: true
})
};
fetch('https://app.indexing.co/dw/pipelines', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.indexing.co/dw/pipelines",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'transformation' => '<string>',
'filter' => '<string>',
'filterKeys' => [
'<string>'
],
'networks' => [
'<string>'
],
'delivery' => [
'adapter' => '<string>',
'connection' => '<string>',
'connectionUri' => '<string>',
'table' => '<string>',
'uniqueKeys' => [
'<string>'
]
],
'enabled' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.indexing.co/dw/pipelines"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"transformation\": \"<string>\",\n \"filter\": \"<string>\",\n \"filterKeys\": [\n \"<string>\"\n ],\n \"networks\": [\n \"<string>\"\n ],\n \"delivery\": {\n \"adapter\": \"<string>\",\n \"connection\": \"<string>\",\n \"connectionUri\": \"<string>\",\n \"table\": \"<string>\",\n \"uniqueKeys\": [\n \"<string>\"\n ]\n },\n \"enabled\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.indexing.co/dw/pipelines")
.header("X-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"transformation\": \"<string>\",\n \"filter\": \"<string>\",\n \"filterKeys\": [\n \"<string>\"\n ],\n \"networks\": [\n \"<string>\"\n ],\n \"delivery\": {\n \"adapter\": \"<string>\",\n \"connection\": \"<string>\",\n \"connectionUri\": \"<string>\",\n \"table\": \"<string>\",\n \"uniqueKeys\": [\n \"<string>\"\n ]\n },\n \"enabled\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.indexing.co/dw/pipelines")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"transformation\": \"<string>\",\n \"filter\": \"<string>\",\n \"filterKeys\": [\n \"<string>\"\n ],\n \"networks\": [\n \"<string>\"\n ],\n \"delivery\": {\n \"adapter\": \"<string>\",\n \"connection\": \"<string>\",\n \"connectionUri\": \"<string>\",\n \"table\": \"<string>\",\n \"uniqueKeys\": [\n \"<string>\"\n ]\n },\n \"enabled\": true\n}"
response = http.request(request)
puts response.read_body{
"message": "<string>"
}{
"error": "<string>"
}Deploying Pipelines
Create
Create or update a distributed pipeline
POST
/
pipelines
cURL
curl --request POST \
--url https://app.indexing.co/dw/pipelines \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"name": "<string>",
"transformation": "<string>",
"filter": "<string>",
"filterKeys": [
"<string>"
],
"networks": [
"<string>"
],
"delivery": {
"adapter": "<string>",
"connection": "<string>",
"connectionUri": "<string>",
"table": "<string>",
"uniqueKeys": [
"<string>"
]
},
"enabled": true
}
'import requests
url = "https://app.indexing.co/dw/pipelines"
payload = {
"name": "<string>",
"transformation": "<string>",
"filter": "<string>",
"filterKeys": ["<string>"],
"networks": ["<string>"],
"delivery": {
"adapter": "<string>",
"connection": "<string>",
"connectionUri": "<string>",
"table": "<string>",
"uniqueKeys": ["<string>"]
},
"enabled": True
}
headers = {
"X-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
transformation: '<string>',
filter: '<string>',
filterKeys: ['<string>'],
networks: ['<string>'],
delivery: {
adapter: '<string>',
connection: '<string>',
connectionUri: '<string>',
table: '<string>',
uniqueKeys: ['<string>']
},
enabled: true
})
};
fetch('https://app.indexing.co/dw/pipelines', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.indexing.co/dw/pipelines",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'transformation' => '<string>',
'filter' => '<string>',
'filterKeys' => [
'<string>'
],
'networks' => [
'<string>'
],
'delivery' => [
'adapter' => '<string>',
'connection' => '<string>',
'connectionUri' => '<string>',
'table' => '<string>',
'uniqueKeys' => [
'<string>'
]
],
'enabled' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.indexing.co/dw/pipelines"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"transformation\": \"<string>\",\n \"filter\": \"<string>\",\n \"filterKeys\": [\n \"<string>\"\n ],\n \"networks\": [\n \"<string>\"\n ],\n \"delivery\": {\n \"adapter\": \"<string>\",\n \"connection\": \"<string>\",\n \"connectionUri\": \"<string>\",\n \"table\": \"<string>\",\n \"uniqueKeys\": [\n \"<string>\"\n ]\n },\n \"enabled\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.indexing.co/dw/pipelines")
.header("X-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"transformation\": \"<string>\",\n \"filter\": \"<string>\",\n \"filterKeys\": [\n \"<string>\"\n ],\n \"networks\": [\n \"<string>\"\n ],\n \"delivery\": {\n \"adapter\": \"<string>\",\n \"connection\": \"<string>\",\n \"connectionUri\": \"<string>\",\n \"table\": \"<string>\",\n \"uniqueKeys\": [\n \"<string>\"\n ]\n },\n \"enabled\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.indexing.co/dw/pipelines")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"transformation\": \"<string>\",\n \"filter\": \"<string>\",\n \"filterKeys\": [\n \"<string>\"\n ],\n \"networks\": [\n \"<string>\"\n ],\n \"delivery\": {\n \"adapter\": \"<string>\",\n \"connection\": \"<string>\",\n \"connectionUri\": \"<string>\",\n \"table\": \"<string>\",\n \"uniqueKeys\": [\n \"<string>\"\n ]\n },\n \"enabled\": true\n}"
response = http.request(request)
puts response.read_body{
"message": "<string>"
}{
"error": "<string>"
}Destinations
There are currently three flavors of destinations available via self-service APIs: Webhooks, WebSockets, and Postgres. There are 16 total that are currently supported by Indexing Co generally though - reach out if you need something else!Webhooks
Here’s an example payload for creating a pipeline that delivers to a webhook:{
...
"delivery": {
"adapter": "HTTP",
"connection": {
"host": "https://webhook.site/...",
"headers": {
"some-auth-key": "some-auth-key"
}
}
},
...
}
Signing deliveries (HMAC)
For sensitive payloads you can have each delivery signed so your endpoint can verify it came from us, was not modified in transit, and is not a replay. Add asigning block to the webhook connection:
{
...
"delivery": {
"adapter": "HTTP",
"connection": {
"host": "https://your-app.com/webhooks/indexing",
"headers": {
"some-auth-key": "some-auth-key"
},
"signing": {
"secret": "whsec_your_shared_secret",
"header": "X-Indexing-Signature",
"tsHeader": "X-Indexing-Timestamp"
}
}
},
...
}
header and tsHeader are optional and default to X-Indexing-Signature and X-Indexing-Timestamp. Each delivery then carries:
| Header | Value |
|---|---|
X-Indexing-Timestamp | Unix time in seconds when the request was signed |
X-Indexing-Signature | sha256=<hex>, where <hex> = HMAC_SHA256(secret, "<timestamp>.<body>") |
"<timestamp>.<rawBody>" and compare it to X-Indexing-Signature in constant time:
const crypto = require('crypto');
function verify(req, secret) {
const ts = req.header('X-Indexing-Timestamp');
const sig = req.header('X-Indexing-Signature'); // "sha256=<hex>"
if (!ts || !sig) return false;
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // reject replays
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(`${ts}.${req.rawBody}`).digest('hex');
const a = Buffer.from(sig);
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Verify against the raw request body bytes, not a re-serialized JSON object — whitespace or key-ordering differences will break the comparison. In Express, capture the raw body with
express.json({ verify: (req, _res, buf) => { req.rawBody = buf.toString('utf8'); } }).WebSockets
Here’s an example payload for creating a pipeline that delivers to a websocket:{
...
"delivery": {
"adapter": "WEBSOCKET",
"connection": {
"host": "ws://websocket-host.com/...",
"headers": {
"some-auth-key": "some-auth-key"
}
}
},
...
}
Postgres
Here’s an example payload for creating a pipeline that delivers to a Postgres database:{
...
"delivery": {
"adapter": "POSTGRES",
"connectionUri": "postgres://...",
"table": "vitalik_token_transfers",
"uniqueKeys": ["transaction_hash", "log_index"]
},
...
}
Make sure your database table is already setup! Importantly, this also includes ensuring that there’s a unique / primary key index on the table matching the provided
uniqueKeys in the pipeline.