Vein Explorer provides generated supply chain analysis. Ticker symbols are indicative only and are not investment advice. Verify symbols with your broker before trading.

API

Create keys for programmatic access, then call /v1/public/traces with the x-api-key header.

API keys

Keys start with vk_. The full secret is shown once at creation. Usage is metered per key (default 1,000 requests/month).

Loading API keys…

API reference

Programmatic access to supply-chain traces. All public endpoints live under https://vein-api-production.up.railway.app/v1/public/traces and require an API key. Interactive Swagger docs are at /docs.

Base URL & headers

FieldTypeRequiredDescription
Base URLstringYeshttps://vein-api-production.up.railway.app/v1 — all paths below are relative to this prefix.
Content-TypeheaderYesapplication/json on POST requests.
x-api-keyheaderYesYour secret key (vk_…). Also accepted as Authorization: Bearer vk_…
POST/public/traces

Create a trace

Run a root supply-chain decomposition for a product, component, or service.

Request body
FieldTypeRequiredDescription
querystringYesWhat to trace, e.g. "Electric Vehicle" or "NVDA GPU".
workspaceIdstringNoOptional workspace to assign the trace to. Ignored if the API key is workspace-scoped.
Example
curl -X POST "https://vein-api-production.up.railway.app/v1/public/traces" \
  -H "Content-Type: application/json" \
  -H "x-api-key: vk_YOUR_KEY" \
  -d '{"query": "Electric Vehicle"}'
Response — 201 / 200

Returns a full trace object (same shape as GET). Root expansion can take several seconds.

{
  "id": "clx…",
  "publicId": "a1b2c3d4",
  "query": "Electric Vehicle",
  "rootId": "n_1",
  "nodes": {
    "n_1": {
      "id": "n_1",
      "name": "Electric Vehicle",
      "depth": 0,
      "parent": null,
      "children": ["n_2", "n_3"],
      "expanded": true,
      "category": "Product",
      "summary": "Battery-electric road vehicle…",
      "is_tradeable": false,
      "tickers": [],
      "criticality": "",
      "is_chokepoint": false,
      "chokepoint_reason": "",
      "sources": ["https://…"]
    },
    "n_2": {
      "id": "n_2",
      "name": "Lithium-ion battery pack",
      "depth": 1,
      "parent": "n_1",
      "children": [],
      "expanded": false,
      "category": "Component",
      "summary": "High-voltage traction battery",
      "is_tradeable": true,
      "tickers": [
        {
          "symbol": "TSLA",
          "name": "Tesla Inc",
          "type": "stock",
          "trend": "Vertically integrated pack production",
          "market_position": "Leading EV OEM"
        }
      ],
      "criticality": "high",
      "is_chokepoint": false,
      "chokepoint_reason": "",
      "sources": []
    }
  },
  "userId": "usr_…",
  "workspaceId": null,
  "createdAt": "2026-06-25T12:00:00.000Z",
  "updatedAt": "2026-06-25T12:00:00.000Z"
}
GET/public/traces/:id

Get a trace

Fetch a trace you own (or in a workspace your key can access). :id accepts the internal id or shareable publicId.

Example
curl "https://vein-api-production.up.railway.app/v1/public/traces/a1b2c3d4" \
  -H "x-api-key: vk_YOUR_KEY"
Response — 200

Same trace object as create. Returns 404 if not found or not accessible.

POST/public/traces/:id/expand

Expand a node

Decompose one unexpanded node one level deeper. Pick nodeId from nodes[nodeId] where expanded is false.

Request body
FieldTypeRequiredDescription
nodeIdstringYesKey from the trace nodes map, e.g. "n_2".
Example
curl -X POST "https://vein-api-production.up.railway.app/v1/public/traces/clx…/expand" \
  -H "Content-Type: application/json" \
  -H "x-api-key: vk_YOUR_KEY" \
  -d '{"nodeId": "n_2"}'
Response — 200

Updated trace with the node marked expanded: true and new child nodes appended. Repeating expand on an already-expanded node returns the trace unchanged.

Node fields

FieldTypeRequiredDescription
idstringNoStable node id within the trace graph.
namestringNoSupply-chain node label.
depthnumberNo0 = root; increases downstream.
parentstring | nullNoParent node id.
childrenstring[]NoChild node ids (may be unexpanded stubs).
expandedbooleanNoWhether this node has been expanded.
categorystringNoe.g. Component, Raw Material, Commodity.
summarystringNoOne-sentence description.
is_tradeablebooleanNoWhether public tickers are relevant.
tickersTicker[]NoUp to 4 symbols with trend and market_position.
criticalityhigh | medium | low | ""NoHow irreplaceable to parent.
is_chokepointbooleanNoHidden high-impact dependency flag.
chokepoint_reasonstringNoSet when is_chokepoint is true.
sourcesstring[]NoOptional https URLs used for grounding.

Errors & limits

FieldTypeRequiredDescription
401 UnauthorizedNoMissing, invalid, or revoked API key.
403 ForbiddenNoMonthly key limit exceeded, plan depth limit, or unavailable plan feature.
404 Not FoundNoTrace or node does not exist, or you lack access.
429 Too Many RequestsNoRate limit on unauthenticated web endpoints (not API-key routes).

Each API call increments your key's monthly usage (default 1,000 calls/month). Workspace-scoped keys automatically assign new traces to that workspace.

Typical workflow

# 1. Create root trace
TRACE=$(curl -s -X POST "https://vein-api-production.up.railway.app/v1/public/traces" \
  -H "Content-Type: application/json" \
  -H "x-api-key: vk_YOUR_KEY" \
  -d '{"query": "Data Center"}')

ID=$(echo "$TRACE" | jq -r '.id')
NODE=$(echo "$TRACE" | jq -r '.nodes | to_entries[] | select(.value.expanded == false) | .key' | head -1)

# 2. Expand first unexpanded child
curl -s -X POST "https://vein-api-production.up.railway.app/v1/public/traces/$ID/expand" \
  -H "Content-Type: application/json" \
  -H "x-api-key: vk_YOUR_KEY" \
  -d "{\"nodeId\": \"$NODE\"}" | jq '.nodes | keys | length'