Endpoints
An endpoint is your second product type. Where an asset returns an insight (a value, a table, or a chart), an endpoint serves raw rows of structured data — a queryable REST data feed exposed directly from your database.
This page is the management reference (seller side): creating, configuring, testing, and keying endpoints via the Management API. For the concept and lifecycle see Endpoints Overview; for the customer-facing fetch contract see Endpoint API Reference.
Doc note: this page replaces a previous speculative "insights" page that described endpoints (forecasting, streaming) that aren't part of the live API. If you're maintaining the docs, consider renaming this page's slug from
insights-endpointsto something likeendpoints-management— "insights" is misleading for the raw-data product. Update the cross-links in Assets and Use Cases & Examples if you do.
All routes below live on the Management API (https://api.spartera.com) under your company and use an analytics key (sk_spartera_...) in the x-api-key header.
https://api.spartera.com/companies/{company_id}/endpoints
Code blocks assume
BASE_URL,COMPANY_ID, and aHEADERSdict with yourx-api-key. See Python Examples for setup.
Asset or Endpoint?
| You want to return... | Create a... |
|---|---|
| A single value or insight | Calculation Asset |
| A chart or graph | Visualization Asset |
| Multiple rows of structured data | Endpoint |
"What's the average air distance for an NFL quarterback?" → one number → asset. "Give me air distance per quarterback" → rows → endpoint.
The Endpoint Object
| Field | Required | Description |
|---|---|---|
name | ✅ | Human-readable name (shown in marketplace) |
description | ✅ | What rows the endpoint returns |
connection_id | ✅ | Which database connection to query |
source_schema_name | ✅ | Schema where the source table lives |
source_table_name | ✅ | Table being exposed |
endpoint_schema | ✅ | Column-level config: which columns, aliases, aggregations, filters |
access_method | ✅ | OPEN, API_KEY, or IP (most use API_KEY) |
max_records_per_request | Row cap per request (default 1,000) | |
rate_limit_number / rate_limit_period / rate_limit_granularity | Optional per-buyer/IP rate limits | |
sell_in_marketplace | true = public listing; false = direct B2B only | |
data_time_period_start / data_time_period_end | When your data records begin/end | |
data_source_refresh_frequency | How often the source data updates | |
top_questions | Buyer-facing questions the data answers (powers search relevance/SEO) |
Pricing is not on the endpoint record — it's set separately via the price API (see Pricing & Publishing below).
List Endpoints
GET /companies/{company_id}/endpointsSupports pagination, filtering, and sorting (same conventions as Assets — page, per_page, sort_field, sort_direction).
r = requests.get(f"{BASE_URL}/companies/{COMPANY_ID}/endpoints", headers=HEADERS)
for ep in r.json()["data"]:
print(ep["endpoint_id"], ep["name"], ep["slug"])Get an Endpoint
GET /companies/{company_id}/endpoints/{endpoint_id}Discover Columns (Before You Configure)
Before building endpoint_schema, inspect what the source connection exposes.
GET /companies/{company_id}/connections/{connection_id}/describeQuery parameters:
| Param | Default | Description |
|---|---|---|
include_fields | true | Include column/field details |
schemas | Comma-separated schemas to limit the scan | |
tables | Comma-separated tables to limit the scan |
r = requests.get(
f"{BASE_URL}/companies/{COMPANY_ID}/connections/{CONNECTION_ID}/describe",
headers=HEADERS,
params={"schemas": "nfl", "tables": "passing_stats"}
)
print(r.json()["data"])To populate a column's allowed filter values, scan it for distinct values:
POST /companies/{company_id}/endpoints/{endpoint_id}/scan_columnr = requests.post(
f"{BASE_URL}/companies/{COMPANY_ID}/endpoints/{endpoint_id}/scan_column",
headers=HEADERS,
json={"column": "team", "limit": 100000} # column required; limit default 100000
)
print(r.json()["data"]["values"])Create an Endpoint
POST /companies/{company_id}/endpointspayload = {
"company_id": COMPANY_ID,
"user_id": USER_ID,
"name": "NFL Passing Yards by Team",
"description": "Per-team passing yardage for the current NFL season.",
"connection_id": CONNECTION_ID,
"source_schema_name": "nfl",
"source_table_name": "passing_stats",
"access_method": "API_KEY",
"max_records_per_request": 1000,
"sell_in_marketplace": False, # save as draft; publish later
"data_source_refresh_frequency": "WEEKLY",
"endpoint_schema": { # illustrative — see note below
"columns": [
{"name": "team", "alias": "Team", "visible": True},
{"name": "passing_yards", "alias": "Passing Yards", "visible": True}
]
}
}
r = requests.post(f"{BASE_URL}/companies/{COMPANY_ID}/endpoints",
headers=HEADERS, json=payload)
endpoint_id = r.json()["data"]["endpoint_id"]
print(f"Endpoint created: {endpoint_id}")On
endpoint_schema: the shape above is illustrative. The exact per-column keys (aliases, aggregations, filters, hidden flags, valid values) are easiest to obtain by starting from a/describeresponse, or by configuring columns in the dashboard's Schema Config table and reading the saved endpoint back withGET .../endpoints/{endpoint_id}. Build it there first if you're unsure of the precise structure.
Update an Endpoint
PATCH /companies/{company_id}/endpoints/{endpoint_id}Send only the fields you want to change. Updates invalidate the marketplace cache so changes appear immediately on the product page.
requests.patch(f"{BASE_URL}/companies/{COMPANY_ID}/endpoints/{endpoint_id}",
headers=HEADERS,
json={"max_records_per_request": 5000,
"description": "Now includes 2026 season."})Delete an Endpoint
DELETE /companies/{company_id}/endpoints/{endpoint_id}Deleting removes the endpoint from the marketplace and invalidates its cache.
Test an Endpoint
Run the endpoint against real data with a small row count to confirm the shape buyers will receive. Free — no credits consumed.
GET /companies/{company_id}/endpoints/{endpoint_id}/testAn optional limit (default 10) controls how many sample rows come back.
r = requests.get(f"{BASE_URL}/companies/{COMPANY_ID}/endpoints/{endpoint_id}/test",
headers=HEADERS)
print(r.json()["data"])Get the Public URL & Example Requests
Once configured, fetch the buyer-facing URL plus ready-made example requests (cURL, Python, JavaScript):
GET /companies/{company_id}/endpoints/{endpoint_id}/urlinfo = requests.get(f"{BASE_URL}/companies/{COMPANY_ID}/endpoints/{endpoint_id}/url",
headers=HEADERS).json()["data"]
print(info["endpoint_url"]) # e.g. https://acme.api.spartera.com/endpoints/v1/nfl-stats
print(info["example_requests"]["python"])Endpoint Key Management
Endpoints are consumed with endpoint keys (ep_...), which are read-only and scoped to a single endpoint. Marketplace buyers get one auto-provisioned on first fetch; for direct B2B customers you mint them yourself here.
List Keys
GET /companies/{company_id}/endpoints/{endpoint_id}/keysReturns the endpoint-type keys linked to this endpoint (masked values). Requires permission to view API keys.
Create a Key
POST /companies/{company_id}/endpoints/{endpoint_id}/keysRequires a Data Engineer (role 3) key or above. The plain-text value is returned once, in data.plain_text_value — save it immediately.
r = requests.post(f"{BASE_URL}/companies/{COMPANY_ID}/endpoints/{endpoint_id}/keys",
headers=HEADERS,
json={"name": "Acme Corp Production",
"expiration_date_utc": "2026-12-31T23:59:59Z"}) # expiry optional
print(r.json()["data"]["plain_text_value"]) # ep_... — shown only nowDelete a Key
DELETE /companies/{company_id}/endpoints/{endpoint_id}/keys/{api_key_id}→ Full key model, roles, and rotation: API Keys.
Pricing & Publishing
Pricing uses the same price API as assets:
POST /companies/{company_id}/endpoints/{endpoint_id}/pricesrequests.post(f"{BASE_URL}/companies/{COMPANY_ID}/endpoints/{endpoint_id}/prices",
headers=HEADERS, json={"price_usd": 2.00})Publish by setting sell_in_marketplace (and the marketplace metadata) via PATCH:
requests.patch(f"{BASE_URL}/companies/{COMPANY_ID}/endpoints/{endpoint_id}",
headers=HEADERS,
json={"sell_in_marketplace": True,
"data_source_refresh_frequency": "WEEKLY"})Publishing requires Stripe to be connected for your company (→ Quickstart Guide, Step 5). To unpublish, set sell_in_marketplace back to False.
Executing an Endpoint
There are two execution paths — don't confuse them:
| Route | Auth | Who | Notes |
|---|---|---|---|
GET /companies/{company_id}/endpoints/{endpoint_id}/execute | Analytics key (sk_spartera_) | You / same-company | Internal fetch with ?start=&limit=. No credits for company-owned use. |
GET https://{handle}.api.spartera.com/endpoints/v1/{slug} | Endpoint key (ep_) | Buyers | The public, billable, customer-facing route. |
For the public contract — response envelope, pagination, filtering, status codes — see Endpoint API Reference.
# Internal / same-company preview against live data
r = requests.get(f"{BASE_URL}/companies/{COMPANY_ID}/endpoints/{endpoint_id}/execute",
headers=HEADERS, params={"start": 0, "limit": 100})
print(r.json())Usage Statistics
GET /companies/{company_id}/endpoints/{endpoint_id}/statsReturns a usage summary (total_requests, unique_ips, avg_response_time_ms, rate_limit_hits, requests_by_day). Accepts a days query param (default 30).
Note: usage tracking is still being wired up — this route currently returns zeroed placeholder values until that lands.
Recommendations
GET /companies/{company_id}/endpoints/{endpoint_id}/recommendationsPublic (no auth). Returns a mixed, endpoint-biased list of related endpoints and assets; any asset sharing the endpoint's connection_id surfaces as the associated analytic. Query params: limit (default 12, max 50), min_score (default 0.1, range 0.0–1.0).
HTTP Status Codes
| Code | Meaning |
|---|---|
200 OK | Success |
400 Bad Request | Invalid parameters (e.g. missing column on scan) |
401 Unauthorized | Missing or invalid API key |
403 Forbidden | Insufficient role/permissions (e.g. creating a key below role 3) |
404 Not Found | Endpoint doesn't exist |
429 Too Many Requests | Rate limit exceeded |
Related Pages
- Endpoints Overview — Concept, lifecycle, and best practices
- Endpoint API Reference — Customer-facing fetch route and response envelope
- Assets — The other product type: insights, charts, and predictions
- API Keys — Endpoint keys vs analytics keys
- Connections — Database connections and credentials
- Quickstart Guide — End-to-end seller walkthrough
