Skip to content

Drivers

POST /api/v1/drivers is the synchronous companion to forecasts. You send a RecommendRequestV1 (metadata, optional time series, optional filters) and get an immediate response with the most relevant drivers and their attributions — no polling, no artifacts.

For the full request shape and per-field validation, see POST /api/v1/drivers.

When to use drivers

  • You need driver recommendations right now (UI suggestions, exploratory analysis).
  • You don't need the full forecast pipeline — just the ranked driver list with importance and direction.
  • You want to filter by region / category to scope the recommendation universe.

If you want a forecast that also embeds driver attributions, submit a forecast instead — its external_signals.json artifact carries the same kind of information.

Call the endpoint

bash
cat > drivers_body.json <<'EOF'
{
  "version": "v1",
  "recency_factor": 0.5,
  "timeseries_metadata": {
    "title": "Aluminum price in Europe USD/KG",
    "keywords": ["aluminum", "metals", "commodities"]
  },
  "filters": {
    "categories": [101],
    "regions": [42],
    "limit": 25
  }
}
EOF

curl -sS -X POST https://api.sybilion.dev/api/v1/drivers \
  -H "Authorization: Bearer $SYBILION_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d @drivers_body.json | jq
python
import os

from sybilion import Client

client = Client(token=os.environ["SYBILION_API_TOKEN"])

body = {
    "version": "v1",
    "recency_factor": 0.5,
    "timeseries_metadata": {
        "title": "Aluminum price in Europe USD/KG",
        "keywords": ["aluminum", "metals", "commodities"],
    },
    "filters": {
        "categories": [101],
        "regions": [42],
        "limit": 25,
    },
}

resp = client.raw.api_v1_drivers_post(recommend_request_v1=body)
print(resp)  # passthrough body from the recommendations engine
go
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"go.sybilion.dev/sybilion"
	api "go.sybilion.dev/sybilion/api"
)

func main() {
	c := sybilion.New(sybilion.Options{
		Token: os.Getenv("SYBILION_API_TOKEN"),
	})

	meta := api.NewTimeseriesMetadata("Aluminum price in Europe USD/KG")
	meta.SetKeywords([]string{"aluminum", "metals", "commodities"})

	filters := api.NewFilters()
	filters.SetCategories([]int32{101})
	filters.SetRegions([]int32{42})
	filters.SetLimit(25)

	body := api.NewRecommendRequestV1("v1", 0.5, *meta)
	body.SetFilters(*filters)

	resp, _, err := c.DefaultAPI().
		ApiV1DriversPost(context.Background()).
		RecommendRequestV1(*body).
		Execute()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(resp)
}

The response body is passed through verbatim from the drivers engine: status code, headers, and body. The exact JSON shape evolves with the engine but typically includes a drivers[] array with per-entry driver_name, importance, direction, and correlation fields — the same shape you see in a forecast's external_signals.json artifact.

Filter ids

filters.regions[] and filters.categories[] are integer ids in 19999. Browse valid ids using Regions & categories. The endpoint does not cross-check ids against those listings.

Pricing

You are billed only on 2xx. The cost scales with the number of items the engine returns plus a fixed base fee — the exact rate is shown on the Developers Portal pricing page.

A pre-charge check assumes the worst case — as many billed items as filters.limit allows (default 1000 when omitted). If your available_eur_cents on /me cannot cover that ceiling, the call returns 402 with {"error": "insufficient credits"} and the engine is not invoked. The settled charge after a successful call uses the actual item count returned, which may be lower than the ceiling.

To deduplicate billing across retries, send the same X-Request-ID header on each attempt.

Common errors

CodeCauseWhat to do
402Insufficient available balance for the worst-case ceiling.Top up, or reduce filters.limit so the pre-check fits your balance.
422Validation failure (one detail per response).Inspect details[0].
429Per-minute cap on synchronous billed calls exceeded.Back off; check your tier on /tiers.
502Transport error talking to the engine.Retry with the same X-Request-ID.
503Drivers feature not enabled for your account.Contact [email protected].

Full error envelope: Errors & limits.

See also

[email protected] · Slack · Discord (links in Community page & header icons)