Docs / API

API reference

A CORS-open REST surface under /api/v1, plus a GraphQL endpoint. Data responses are licensed CC-BY-4.0. Discovery is open; the data endpoints take a free account key.

Authentication

The route index (/api/v1) and the intents catalogue (/api/v1/intents) are open. Every other endpoint on this page is metered and answers 401 without a key. Appending .md to any page URL stays open and never costs a credit, which is what “free to read and cite” means in practice.

curl
# Bearer token (preferred)
curl -H "Authorization: Bearer $VIOSCALE_KEY" https://www.vioscale.ai/api/v1/software/nextjs

# or, if your client prefers a custom header
curl -H "X-API-Key: $VIOSCALE_KEY" https://www.vioscale.ai/api/v1/software/nextjs

Keys are free and self-serve at /dashboard/api-keys, and calls are not charged. We ask for an account so usage is attributable, not to bill you.

Response envelope

Every REST response wraps its payload the same way:

json
{
  "data": { /* the payload, shape depends on the endpoint */ },
  "meta": {
    "source": "https://www.vioscale.ai",
    "license": "CC-BY-4.0",
    "generatedAt": "2026-07-06T00:00:00.000Z",
    "disclaimer": "Independent, evidence-based. Every fact carries provenance."
  }
}

Errors return { "error": "…" } with the appropriate status (e.g. 404 for an unknown slug).

Endpoints

MethodPathdataDescription
GET/api/v1ApiIndexSelf-describing index of every endpoint.
GET/api/v1/softwareEntityListItem[]List entities. Query: category, limit, sort=score|name, intent, weights.
GET/api/v1/software/{slug}EntityViewOne entity with all provenanced facts (canonical balanced score). 404 if unknown.
GET/api/v1/categoriesCategoryView[]List all categories (tree).
GET/api/v1/categories/{slug}CategoryViewOne category with its ranked entities. Query: intent, weights.
GET/api/v1/compareComparisonViewAligned comparison. Query: tools=a,b,c (required), intent, weights.
GET/api/v1/searchEntityListItem[]Fuzzy search. Query: q (required), limit, intent, weights.
GET/api/v1/alternatives/{slug}EntityListItem[]Same-category alternatives. Query: limit, intent, weights.
GET/api/v1/signals/{slug}SignalBreakdownViewThe signal breakdown behind an entity's score.
GET/api/v1/intentsIntentCatalogueCatalogue of ranking profiles + signal glossary (for intent/weights).

Intent-conditioned ranking

Every list and ranking endpoint (and the same GraphQL queries) accepts optional re-weighting. The facts and signals never change, only the weight vector does. The balanced default is the canonical, citeable score; pass intent (a named profile) or weights (an explicit override) to re-rank. The resolved profile and normalised weights come back in meta, so you can verify the ranking. Each signal is capped at 0.5 of the total, so no single signal can dominate. See the full catalogue at /api/v1/intents.

shell
# named profile
curl "https://www.vioscale.ai/api/v1/categories/ci-cd?intent=most-secure"

# explicit weights (signal:number, comma-separated)
curl "https://www.vioscale.ai/api/v1/search?q=orm&weights=package_downloads:0.5,dev_activity:0.5"

# GraphQL takes the same args
curl -X POST https://www.vioscale.ai/api/graphql -H 'content-type: application/json' \
  -d '{"query":"{ compare(tools:[\"prisma\",\"drizzle-orm\"], intent:\"most-active\"){ leader } }"}'

# the response meta echoes the applied ranking:
#   "meta": { "profile": "most-secure", "weights": { "security_posture": 0.48, ... } }

Content negotiation

You don't have to use /api/v1 at all. A canonical page URL responds to your Accept header:

curl
curl -H "Accept: application/json" https://www.vioscale.ai/software/nextjs   # → JSON
curl -H "Accept: text/markdown"   https://www.vioscale.ai/software/nextjs   # → Markdown
curl https://www.vioscale.ai/software/nextjs.md                              # → Markdown (suffix)

GraphQL

POST /api/graphql: open GraphiQL in a browser at the same URL. Schema:

graphql schema
type Query {
  software(slug: String!): Entity
  softwareList(category: String, limit: Int): [Entity!]!
  categories: [Category!]!
  category(slug: String!): Category
  compare(tools: [String!]!): Comparison!
  search(q: String!, limit: Int): [Entity!]!
  alternatives(slug: String!, limit: Int): [Entity!]!
}
curl
curl https://www.vioscale.ai/api/graphql \
  -H 'Content-Type: application/json' \
  -d '{"query":"{ compare(tools:[\"prisma\",\"drizzle-orm\"]){ leader entities{ name score{ composite } } } }"}'