# Chat Source: https://docs.useskald.com/docs/api-reference/chat API reference for the chat /api/v1/chat endpoint ## Chat API Ask questions about your knowledge base using an AI agent with optional filtering to focus the search context. ### POST /api/v1/chat **Authentication:** Project API Key from [https://platform.useskald.com](https://platform.useskald.com) **Request (using Project API Key):** ```json theme={null} { "query": "What were the main points discussed in the Q1 meeting?", "stream": false, "system_prompt": "You are a helpful assistant that can answer questions about the memo.", "filters": [ { "field": "source", "operator": "eq", "value": "meeting-notes", "filter_type": "native_field" }, { "field": "tags", "operator": "in", "value": ["q1", "meeting"], "filter_type": "native_field" } ] } ``` **Request (using Token Authentication):** ```json theme={null} { "query": "What were the main points discussed in the Q1 meeting?", "project_id": "project-uuid", "stream": false, "filters": [ { "field": "category", "operator": "eq", "value": "meeting", "filter_type": "custom_metadata" } ] } ``` **Parameters:** * `query` (string, required): The question to ask * `project_id` (UUID, optional): **Only required when using Token Authentication** * `stream` (boolean, optional): Enable streaming responses (default: false) * `system_prompt` (string, optional): A system prompt to guide the chat agent's behavior * `filters` (array of filter objects, optional): Filters to narrow the search context. See [Filters](/docs/api-reference/filters) for detailed documentation. **Filter Support:** Filters are applied during the initial retrieval of relevant context, allowing you to: * Filter by a "workspace" or "team" ID from your side * Focus the chat on specific sources (e.g., only Notion docs) * Query only memos with certain tags * Exclude certain categories of content See [Filters](/docs/api-reference/filters) for complete documentation on filter structure, operators, and examples. **Response (Non-streaming):** ```json theme={null} { "ok": true, "response": "The main points discussed in the Q1 meeting were:\n1. Revenue targets \n2. Hiring plans \n3. Product roadmap", "intermediate_steps": [] } ``` **Response (Streaming):** When `stream: true`, returns Server-Sent Events: ``` Content-Type: text/event-stream : ping data: {"type": "token", "content": "The"} data: {"type": "token", "content": " main"} data: {"type": "done"} ``` ### GET /api/v1/chat Get a list of chats. **Authentication:** Project API Key from [https://platform.useskald.com](https://platform.useskald.com) **Query Parameters:** * `page` (integer, optional): Page number (default: 1) * `page_size` (integer, optional): Page size (default: 20) **Example Response:** ```json theme={null} { "results": [ { "uuid": "84365e7e-381e-47da-9104-8dcc7a83920e", "created_at": "2025-12-13T16:57:45.240Z", "title": "What does undefined do?", "message_count": 2, "last_message_at": "2025-12-13T16:57:45.242Z" } ], "count": 1, "page": 1, "page_size": 1, "total_pages": 1 } ``` * Count: The total number of chats * Page: The page number * Page size: The number of chats per page * Total pages: The total number of pages ### GET /api/v1/chat/:chat\_uuid Get a chat by its UUID. **Authentication:** Project API Key from [https://platform.useskald.com](https://platform.useskald.com) **Path Parameters:** * `:chat_uuid` (string, required): The UUID of the chat **Example Response:** ```json theme={null} { "uuid": "4a71fd8b-2ca0-42d8-9bfd-8d11d080ecf3", "created_at": "2025-11-22T01:13:41.113Z", "messages": [ { "uuid": "e03af6a7-da4d-4508-9057-4dcc25eec7e0", "content": "what's 2+2?", "sent_by": "user", "sent_at": "2025-11-22T01:13:41.114Z", "client_system_prompt": null }, { "uuid": "d72c88d0-c6d4-4155-8601-c695abac5cab", "content": "2+2 is 4", "sent_by": "model", "sent_at": "2025-11-22T01:13:41.115Z", "client_system_prompt": null } ] } ``` ### Error Responses **Missing query (400):** ```json theme={null} { "error": "Query is required" } ``` **Invalid filters (400):** ```json theme={null} { "error": "Filters must be a list" } ``` **Invalid filter structure (400):** ```json theme={null} { "error": "Invalid filter: " } ``` **Agent error (500):** ```json theme={null} { "error": "Agent error: " } ``` # Filters Source: https://docs.useskald.com/docs/api-reference/filters Advanced filtering for search, chat, and generate endpoints ## Overview Filters allow you to narrow down results and context in the `/api/v1/search`, `/api/v1/chat`, and `/api/v1/generate` endpoints. You can filter by native memo fields or custom metadata fields using various operators. Filters are applied using AND logic - all filters must match for a memo to be included. ## Filter Structure Each filter object has the following structure: ```json theme={null} { "field": "field_name", "operator": "operator_name", "value": "value or [array]", "filter_type": "native_field | custom_metadata" } ``` **Required Fields:** * `field` (string): The field name to filter on * `operator` (string): The comparison operator to use * `value` (string | array): The value to compare against (arrays required for `in` and `not_in`) * `filter_type` (string): Either `native_field` or `custom_metadata` ## Filter Types ### Native Fields Filter on built-in memo properties using `filter_type: "native_field"`: * `title` - Memo title * `source` - Source system name * `client_reference_id` - External reference ID * `tags` - Memo tags (must use `in` or `not_in` operator with array value) **Example:** ```json theme={null} { "field": "source", "operator": "eq", "value": "notion", "filter_type": "native_field" } ``` ### Custom Metadata Filter on any field from a memo's `metadata` JSON object using `filter_type: "custom_metadata"`: **Example:** ```json theme={null} { "field": "category", "operator": "contains", "value": "tutorial", "filter_type": "custom_metadata" } ``` This filters memos where `metadata.category` contains "tutorial". ## Operators ### Equality Operators * `eq` - Equals (exact match) * `neq` - Not equals **Example:** ```json theme={null} { "field": "source", "operator": "eq", "value": "confluence", "filter_type": "native_field" } ``` ### String Operators * `contains` - Contains substring (case-insensitive) * `startswith` - Starts with (case-sensitive) * `endswith` - Ends with (case-sensitive) **Example:** ```json theme={null} { "field": "title", "operator": "contains", "value": "meeting", "filter_type": "native_field" } ``` ### Array Operators * `in` - Value is in array (requires array value) * `not_in` - Value is not in array (requires array value) **Example:** ```json theme={null} { "field": "source", "operator": "in", "value": ["notion", "confluence", "docs"], "filter_type": "native_field" } ``` **Tags Example (always requires array):** ```json theme={null} { "field": "tags", "operator": "in", "value": ["meeting", "q1"], "filter_type": "native_field" } ``` ## Combining Filters Multiple filters use AND logic - all filters must match for a memo to be included in results. **Example:** ```json theme={null} { "query": "python tutorial", "search_method": "chunk_vector_search", "filters": [ { "field": "source", "operator": "eq", "value": "docs.python.org", "filter_type": "native_field" }, { "field": "level", "operator": "eq", "value": "beginner", "filter_type": "custom_metadata" }, { "field": "tags", "operator": "in", "value": ["tutorial"], "filter_type": "native_field" } ] } ``` This returns only memos where: * Title/content matches "python tutorial" AND * Source equals "docs.python.org" AND * Metadata field "level" equals "beginner" AND * Has at least one tag in \["tutorial"] ## Common Filter Patterns ### Filter by Source Limit results to specific source systems: ```json theme={null} { "field": "source", "operator": "in", "value": ["notion", "confluence"], "filter_type": "native_field" } ``` ### Filter by Tags Include memos with specific tags: ```json theme={null} { "field": "tags", "operator": "in", "value": ["meeting", "important"], "filter_type": "native_field" } ``` Exclude memos with specific tags: ```json theme={null} { "field": "tags", "operator": "not_in", "value": ["archived", "draft"], "filter_type": "native_field" } ``` ### Filter by Custom Metadata Filter by any custom metadata field: ```json theme={null} { "field": "department", "operator": "eq", "value": "engineering", "filter_type": "custom_metadata" } ``` ### Partial String Match Find memos with titles containing specific text: ```json theme={null} { "field": "title", "operator": "contains", "value": "roadmap", "filter_type": "native_field" } ``` ### Multiple Conditions Combine filters for precise results: ```json theme={null} { "filters": [ { "field": "source", "operator": "eq", "value": "product-docs", "filter_type": "native_field" }, { "field": "status", "operator": "eq", "value": "published", "filter_type": "custom_metadata" }, { "field": "tags", "operator": "in", "value": ["feature", "specification"], "filter_type": "native_field" } ] } ``` ## Error Responses **Invalid filter structure (400):** ```json theme={null} { "error": "Invalid filter: " } ``` **Common filter errors:** * Missing required fields (`field`, `operator`, `value`, `filter_type`) * Invalid operator (must be one of: `eq`, `neq`, `contains`, `startswith`, `endswith`, `in`, `not_in`) * Invalid filter\_type (must be `native_field` or `custom_metadata`) * Invalid native field (must be `title`, `source`, `client_reference_id`, or `tags`) * Tags filter must use `in` or `not_in` operator with array value * `in` and `not_in` operators require array value ## Using Filters Across Endpoints ### Search Endpoint Filters narrow down search results: ```json theme={null} POST /api/v1/search { "query": "api documentation", "search_method": "chunk_vector_search", "filters": [ { "field": "source", "operator": "eq", "value": "technical-docs", "filter_type": "native_field" } ] } ``` See [Search API](/docs/api-reference/search) for details. ### Chat Endpoint Filters control which memos are used as context for chat responses: ```json theme={null} POST /api/v1/chat { "query": "What are our Q1 goals?", "filters": [ { "field": "tags", "operator": "in", "value": ["q1", "goals"], "filter_type": "native_field" } ] } ``` See [Chat API](/docs/api-reference/chat) for details. ### Generate Endpoint Filters determine which memos provide context for document generation: ```json theme={null} POST /api/v1/generate { "prompt": "Create a technical overview document", "filters": [ { "field": "document_type", "operator": "eq", "value": "specification", "filter_type": "custom_metadata" } ] } ``` See [Generate API](/docs/api-reference/generate-doc) for details. ## Tips and Best Practices 1. **Use specific filters** - Narrow your scope to improve relevance and reduce noise 2. **Combine native and custom fields** - Mix source/tags filters with metadata filters for precision 3. **Test filters incrementally** - Add filters one at a time to understand their impact 4. **Empty filters array** - Equivalent to no filters, searches entire project 5. **Case sensitivity** - `contains` is case-insensitive, but `startswith` and `endswith` are case-sensitive 6. **Tags always use arrays** - Even for single tag, use `["tag"]` format with `in` or `not_in` # Introduction Source: https://docs.useskald.com/docs/api-reference/introduction Understand general concepts and response codes ### Base URL The Skald API is built on REST principles. We enforce HTTPS in every request to improve data security, integrity, and privacy. The API does not support HTTP. All requests contain the following base URL: ```javascript theme={null} https://api.useskald.com ``` ### Authentication Each Project inside an Organization on Skald have it's own API key. It follows the format: **sk\_proj\_xxxxxxxxxxxxxxxxxxxxxxx** To authenticate you need to add an Authorization header with the contents of the header being Bearer sk\_proj\_xxxxxxxxx where sk\_proj\_xxxxxxxxx is your project API Key. ```javascript theme={null} Authorization: Bearer sk_proj_xxxxxxxxx ``` ### Response codes Skald uses standard HTTP codes to indicate the success or failure of your requests. In general, 2xx HTTP codes correspond to success, 4xx codes are for user-related failures, and 5xx codes are for infrastructure issues. | Status | Description | | ------ | --------------------------------------- | | 200 | Successful request. | | 400 | Check that the parameters were correct. | | 401 | The API key used was missing. | | 403 | The API key used was invalid. | | 404 | The resource was not found. | | 429 | The rate limit was exceeded. | # Memos Source: https://docs.useskald.com/docs/api-reference/memos API reference for the POST /api/v1/memo endpoint ## Memos API Manage your memos, including creating, updating, deleting, and retrieving them. ### POST /api/v1/memo Create a new memo. The memo will be automatically processed (summarized, chunked, and indexed for search). **Authentication:** Project API Key from [https://platform.useskald.com](https://platform.useskald.com) **Request:** ```json theme={null} { "title": "Meeting Notes", "content": "Full content of the memo...", "metadata": { "type": "notes", "author": "John Doe" }, "reference_id": "external-id-123", "tags": ["meeting", "q1"], "source": "notion", "expiration_date": "2024-12-31T23:59:59Z" } ``` **Required Fields:** * `title` (string, max 255 chars) * `content` (string) **Optional Fields:** * `metadata` (object): Custom JSON metadata * `reference_id` (string, max 255 chars): External reference ID * `tags` (array of strings): Tags for categorization * `source` (string, max 255 chars): Source system name * `expiration_date` (datetime): When the memo should expire **Response:** ```json theme={null} { "ok": true } ``` ### GET /api/v1/memo/ Get memo details by UUID or client reference ID. **Authentication:** Project API Key from [https://platform.useskald.com](https://platform.useskald.com) **Query Parameters:** * `id_type` (string, optional): Type of identifier used. Must be either: * `memo_uuid` (default) - Use memo UUID * `reference_id` - Use client\_reference\_id **Examples:** Get by UUID (default): ``` GET /api/v1/memo/550e8400-e29b-41d4-a716-446655440000 ``` Get by client reference ID: ``` GET /api/v1/memo/external-id-123?id_type=reference_id ``` **Response:** ```json theme={null} { "uuid": "memo-uuid", "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-15T10:30:00Z", "title": "Meeting Notes", "content": "Full content of the memo...", "summary": "Discussion about Q1 goals", "content_length": 1234, "metadata": { "type": "notes" }, "client_reference_id": "external-id-123", "source": "notion", "type": "document", "expiration_date": "2024-12-31T23:59:59Z", "archived": false, "pending": false, "tags": [ { "uuid": "tag-uuid", "tag": "meeting" } ], "chunks": [ { "uuid": "chunk-uuid", "chunk_content": "First chunk content...", "chunk_index": 0 } ] } ``` **Error Responses:** Invalid id\_type (400): ```json theme={null} { "error": "id_type must be either 'memo_uuid' or 'reference_id'" } ``` Memo not found (404): ```json theme={null} { "error": "Memo not found" } ``` ### PATCH /api/v1/memo/ Partially update an existing memo by UUID or client reference ID. If the content is updated, all related data (summary, tags, chunks) will be deleted and the memo will be reprocessed. **Authentication:** Project API Key from [https://platform.useskald.com](https://platform.useskald.com) **Query Parameters:** * `id_type` (string, optional): Type of identifier used. Must be either: * `memo_uuid` (default) - Use memo UUID * `reference_id` - Use client\_reference\_id **Examples:** Update by UUID (default): ``` PATCH /api/v1/memo/550e8400-e29b-41d4-a716-446655440000 ``` Update by client reference ID: ``` PATCH /api/v1/memo/external-id-123?id_type=reference_id ``` **Request:** ```json theme={null} { "title": "Updated Title", "metadata": { "type": "updated" }, "client_reference_id": "new-ref-id", "source": "updated-source", "expiration_date": "2025-12-31T23:59:59Z", "content": "Updated content..." } ``` **All Fields Optional:** * `title` (string, max 255 chars): Update the memo title * `metadata` (object): Update custom JSON metadata * `client_reference_id` (string, max 255 chars): Update external reference ID * `source` (string, max 255 chars): Update source system name * `expiration_date` (datetime): Update expiration date * `content` (string): Update the memo content (triggers reprocessing) **Response:** ```json theme={null} { "ok": true } ``` **Notes:** * When `content` is updated, the memo is automatically reprocessed (summary, tags, and chunks are regenerated) * When other fields are updated without `content`, related data is preserved **Error Responses:** Invalid id\_type (400): ```json theme={null} { "error": "id_type must be either 'memo_uuid' or 'reference_id'" } ``` Memo not found (404): ```json theme={null} { "error": "Memo not found" } ``` Access denied (403): ```json theme={null} { "error": "Resource does not belong to the project" } ``` or ```json theme={null} { "error": "Access denied" } ``` ### DELETE /api/v1/memo/ Delete a memo by UUID or client reference ID and all its associated data (content, summary, tags, chunks). **Authentication:** Project API Key from [https://platform.useskald.com](https://platform.useskald.com) **Query Parameters:** * `id_type` (string, optional): Type of identifier used. Must be either: * `memo_uuid` (default) - Use memo UUID * `reference_id` - Use client\_reference\_id **Examples:** Delete by UUID (default): ``` DELETE /api/v1/memo/550e8400-e29b-41d4-a716-446655440000 ``` Delete by client reference ID: ``` DELETE /api/v1/memo/external-id-123?id_type=reference_id ``` **Response:** `204 No Content` **Error Responses:** Invalid id\_type (400): ```json theme={null} { "error": "id_type must be either 'memo_uuid' or 'reference_id'" } ``` Memo not found (404): ```json theme={null} { "error": "Memo not found" } ``` Access denied (403): ```json theme={null} { "error": "Resource does not belong to the project" } ``` or ```json theme={null} { "error": "Access denied" } ``` # Search Source: https://docs.useskald.com/docs/api-reference/search API reference for the POST /api/v1/search endpoint ## Search API ### POST /api/v1/search Search through memos using semantic search. **Authentication:** Project API Key from [https://platform.useskald.com](https://platform.useskald.com) **Request (using Project API Key):** ```json theme={null} { "query": "quarterly goals", "limit": 10, "filters": [ { "field": "source", "operator": "eq", "value": "notion", "filter_type": "native_field" }, { "field": "level", "operator": "eq", "value": "beginner", "filter_type": "custom_metadata" }, { "field": "tags", "operator": "in", "value": ["meeting", "q1"], "filter_type": "native_field" } ] } ``` **Request (using Token Authentication):** ```json theme={null} { "query": "quarterly goals", "project_id": "project-uuid", "limit": 10, "filters": [ { "field": "source", "operator": "eq", "value": "notion", "filter_type": "native_field" } ] } ``` **Parameters:** * `query` (string, required): The search query. * `project_id` (UUID, optional): **Only required when using Token Authentication**. * `limit` (integer, optional): Max results to return (1-50, default 10). * `filters` (array of filter objects, optional): Array of filters to apply. See [Filters](/docs/api-reference/filters) for detailed documentation. **Response:** ```json theme={null} { "results": [ { "memo_title": "Meeting Notes", "memo_uuid": "memo-uuid", "chunk_uuid": "chunk-uuid", "chunk_content": "Full content of the chunk...", "memo_summary": "Discussion about Q1 goals", "distance": 0.234 } ] } ``` **Notes:** * `distance` is the vector similarity distance (lower is more similar). * Empty filters array is equivalent to no filters. **Error Responses:** Missing query (400): ```json theme={null} { "error": "Query is required" } ``` Invalid search method (400): ```json theme={null} { "error": "Search method is required and must be one of: title_contains, title_startswith, chunk_vector_search" } ``` Limit too high (400): ```json theme={null} { "error": "Limit must be less than or equal to 50" } ``` Invalid filter (400): ```json theme={null} { "error": "Invalid filter: " } ``` See [Filters](/docs/api-reference/filters) for complete filter documentation and examples. # Knowledge spaces and filters Source: https://docs.useskald.com/docs/filtering How to separate knowledge in Skald and filter information sources on retrieval In Skald, you can create multiple projects to keep data segregated. This is useful when you use Skald for different applications, or when you have a staging and a prod environment, for example. However, inside the same project, there are various use cases where you'd want to be able to filter what information sources are used for a given query, such as when you're using Skald to provide insights scoped to each one of your users. In that case, you should use our filtering capabilities. When creating a memo, there are various optional fields that you can provide that will be attached to the memo, such as `source`, `reference_id`, `tags`, and `metadata`. All of these fields can then be used as filters when using our retrieval APIs, such that search results and chat responses will only query the memos that match the filters. These fields (including all the metadata fields you provide) are indexed so not only will adding filters not affect retrieval performance, it will actually make it faster, by giving our system less context to process. We recommend using `reference_id` to match a memo to an ID in your own system (e.g. a document ID) but other fields can be used for you to create knowledge spaces. For instance, you can use `user_id:12345` as `source` or set `user_id = 12345` as a metadata field. When filtering, you would then use a filter like this: ```json theme={null} { "field": "source", "operator": "eq", "value": "user_id:12345", "filter_type": "native_field" } ``` Or this: ```json theme={null} { "field": "user_id", "operator": "eq", "value": "12345", "filter_type": "custom_metadata" } ``` These filters will **ensure no context other than what matches the filter will be used to process query**. If you have any questions or feedback about filtering, don't hesistate to reach out to `dev@useskald.com`. # Introduction to Skald Source: https://docs.useskald.com/docs/index The API platform for building AI apps ## Overview Skald is an open-source API platform for building AI apps, from internal tools and agents to public-facing apps. We've seen a lot of companies spend hundreds of engineering hours and tens of thousands of dollars building RAGs that then don't perform well, which is why we built Skald. Send context via our SDKs and get search and chat out-of-the-box, so you can get started in minutes. Then configure your RAG engine to fit your exact needs, and evaluate its performance with our built-in evaluation tools. **Node SDK example** ```js theme={null} import { Skald } from '@skald-labs/skald-node'; const skald = new Skald('your-api-key-here'); await skald.createMemo({ title: 'Meeting Notes', content: 'Full content of the memo...' }); const chatRes = await skald.chat({ query: 'What were the main points discussed in the Q1 meeting?' }); console.log(chatRes.response); ``` ## Getting started To use Skald, you can start using our [Cloud version](https://platform.useskald.com/) for free (no credit card required) or [self-host it yourself](/docs/self-host/intro) (MIT license). ## Demo