# SkillDiscs API — LLM Context Bundle Version: f3af5bca Source: [skilldiscs.com/llms.txt](https://skilldiscs.com/llms.txt) Live docs: [API quickstart](https://skilldiscs.com/docs/quickstart) Key pages: - [Home](https://skilldiscs.com/) - [API quickstart](https://skilldiscs.com/docs/quickstart) - [For learners](https://skilldiscs.com/learn) - [For AI agents](https://skilldiscs.com/llm-skills) - [Blog](https://skilldiscs.com/blog) - [Terms](https://skilldiscs.com/terms) - [Privacy](https://skilldiscs.com/privacy) ## What SkillDiscs is SkillDiscs is an agent-first SaaS that turns user-supplied content (URLs, PDFs, YouTube videos, raw text) into structured, vector-indexed "Disks". A Disk is a curated learning artifact: summary, key points, recall questions, concept map, embeddings, and source attribution. Humans curate the source material; AI agents query the resulting clean knowledge over a small REST API. The premise: LLMs hallucinate when they read garbage; the fix is upstream — better source data → better answers. ## Base URL `https://skilldiscs.com/api/v1` ## Authentication Every request requires a Bearer token in the `Authorization` header. Keys are user-scoped and generated from the user's Settings → API Keys page. ``` Authorization: Bearer sk_live_ Content-Type: application/json ``` Keys are private. Anyone with a key can read every Disk in the owner's library, including private (unpublished) ones. Keep keys server-side. ## Endpoints ### POST /api/v1/search Semantic search across all Disks the authenticated user owns or has saved. Returns matching sections sorted by cosine similarity. Use this directly as RAG context for an LLM. Request body: ```json { "query": "string (natural language question, max 1000 chars)", "limit": 10 } ``` Successful response: ```json { "results": [ { "disk_id": "string (10-char nanoid)", "disk_title": "string", "section_index": 0, "section_text": "string (the actual section content)", "key_points": ["string", "..."], "similarity": 0.94, "source_url": "string|null" } ] } ``` Notes: - Each `section_text` is already chunked for RAG; no further splitting needed. - `key_points` are AI-extracted bullets summarising the section. - `similarity` is cosine similarity over 768-dim Gemini embeddings. ### GET /api/v1/disks/:id Fetch the full structured content of one Disk by its 10-char public id. Successful response: ```json { "id": "string", "title": "string", "summary": "string (markdown)", "category": "string", "tags": ["string", "..."], "language": "en|de|fr|es", "sections": [ { "index": 0, "title": "string", "text": "string (markdown)", "key_points": ["string", "..."] } ], "related_disks": [ { "id": "string", "title": "string", "similarity": 0.87 } ], "source_url": "string|null", "source_kind": "text|pdf|youtube|url" } ``` ### GET /api/v1/disks List / filter the authenticated user's Disks. Query params: - `category` (optional): filter by category id - `language` (optional): `en` | `de` | `fr` | `es` - `limit` (optional, default 20, max 100) - `cursor` (optional): pagination token from a previous response Successful response: ```json { "disks": [ { "public_id": "string", "title": "string", "category": "string", "tags": ["string", "..."], "word_count": 4200, "created_at": "2026-04-29T08:30:00Z" } ], "next_cursor": "string|null", "total": 42 } ``` ## Rate limits - 100 requests per minute per API key (sliding window). - On exceeded: HTTP 429 with body `{ "error": "rate_limit_exceeded", "retry_after": }`. - Per-IP rate limiting is not currently enforced — only per-key. ## Error format All error responses follow the same shape: ```json { "error": "string (machine-readable code)", "message": "string (human-readable, optional)" } ``` Common error codes: - `unauthorized` (401): missing or invalid Bearer token - `rate_limit_exceeded` (429): see Rate limits above - `not_found` (404): the requested Disk id doesn't exist or isn't readable by this key - `bad_request` (400): missing or malformed body fields ## Architecture (so you know what you're querying) 1. **Extract** — Crawl4AI for URLs, sidecar PDF service for documents, YouTube transcript API for video. Clean text out, regardless of source wrapper. 2. **Enrich** — Gemini-driven summary + key-point extraction + concept-graph generation + locale-aware tagging. 3. **Index** — Sections embedded with `gemini-embedding-001` (768-dim) and stored in Postgres + pgvector with HNSW indexes. 4. **Serve** — This API. Stateless, RLS-enforced per user. ## Recommended LLM usage pattern ``` User question → POST /api/v1/search { "query": , "limit": 5 } → Build prompt: "Answer using the following context. Cite the disk_title for each point you use. --- " + results.map(r => r.section_text).join('\n\n---\n\n') → Call your LLM ``` ## Quickstart code ```bash # curl curl -X POST https://skilldiscs.com/api/v1/search \ -H "Authorization: Bearer $SKILLDISCS_KEY" \ -H "Content-Type: application/json" \ -d '{"query": "how does photosynthesis work?", "limit": 5}' ``` ```javascript // JavaScript const res = await fetch('https://skilldiscs.com/api/v1/search', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.SKILLDISCS_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ query: 'how does photosynthesis work?', limit: 5 }), }) const { results } = await res.json() ``` ```python # Python import os, requests r = requests.post( "https://skilldiscs.com/api/v1/search", headers={"Authorization": f"Bearer {os.environ['SKILLDISCS_KEY']}"}, json={"query": "how does photosynthesis work?", "limit": 5}, ) results = r.json()["results"] ``` ## What this API does NOT do - It does not run the LLM for you. You bring your own model. - It does not persist user conversations / chat history between calls. - It does not write data — read-only at /api/v1/*. Disk creation happens in the user-facing app or via authenticated user flows. - It does not return raw HTML or PDF binaries — only the structured, cleaned, chunked content. ## Versioning The API path is currently `/api/v1`. Breaking changes ship under `/api/v2` with at least 6 months of dual-running. Non-breaking additions (new optional fields, new endpoints) ship inside v1. ## Privacy + redaction policy (response shape rules) The response includes verbatim source text *only* when the authenticated key owner is reading their own `visibility = 'private'` Disk. Every other access path is redacted: - Owner reading own *private* Disk → full `text` + `sections[].text` - Owner reading own *published* Disk → no `text` field; sections include `key_points` only; an explicit `redacted: true` marker is set on the response. - Any saved-from-someone-else Disk → not exposed via the API at all; browse the public URL at `/d/` instead. Per-search-hit responses include either `section_text` (owner-private path) or `snippet` (≤200 chars, redacted path) — never both. Use the `redacted` boolean on each result to decide. ## EU AI Act Art. 50 — downstream labelling obligation Every summary, recall question, key point, and cover image returned by this API was produced by Google's Gemini family of LLMs. Under EU Regulation 2024/1689 (in force 2 Aug 2026), products that present AI-generated content to end users must label it as such. The API surface flags this on every response: - Disk responses include `ai_generated: true`. - Cover images are tagged with the same flag in their metadata. If you re-publish, re-broadcast, or display SkillDiscs API output to your users, please continue to label it as AI-generated. ## Terms of use for API keys By creating and using a SkillDiscs API key you warrant that: 1. **Custody** — you keep the key server-side and do not share it. Anyone with your key can read every Disk in your library, including private ones; you remain responsible for any traffic the key generates. 2. **Lawful content** — every Disk in your library was processed with either your ownership of the source or a valid right to use it (your own PDFs, public-web URLs whose terms permit AI summarisation, etc.). You indemnify SkillDiscs against third-party claims arising from content you uploaded. 3. **No re-republishing of source** — the verbatim text returned to you for private Disks is for your own consumption / your own AI agent. Do not re-distribute it as a public corpus or feed it to a third-party commercial training pipeline. 4. **Takedowns** — if a rightsholder asks SkillDiscs to remove content you uploaded, the matching Disks may be archived and become unreachable via the API. Submit complaints to https://skilldiscs.com/dmca. Full terms (post-launch): https://skilldiscs.com/terms.