Skip to main content

Instruction Sets API

Instruction Sets are curated collections of documents designed for full-context LLM loading. They allow you to create organized sets of documents that can be shared publicly via a unique URL.

Overview​

FeatureDescription
Max documents20 per set
Max size100 KB total content
Public accessOptional "anyone with link" sharing
OrderingCustom document order with drag & drop

Management Endpoints​

All management endpoints require authentication.

List Instruction Sets​

GET /api/workspaces/{workspaceId}/instruction-sets

Returns all Instruction Sets in the workspace.

Example Request​

curl "https://api.synjar.com/api/workspaces/ws-123/instruction-sets" \
-H "Authorization: Bearer YOUR_API_KEY"

Response​

{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Onboarding Guide",
"description": "Complete onboarding documentation",
"isPublic": true,
"documentCount": 5,
"totalSizeBytes": 45000,
"publicUrl": "https://app.synjar.com/s/550e8400-e29b-41d4-a716-446655440000",
"createdAt": "2025-12-30T10:00:00Z",
"updatedAt": "2025-12-30T14:30:00Z"
}
]
}

Create Instruction Set​

POST /api/workspaces/{workspaceId}/instruction-sets

Creates a new Instruction Set.

Request Body​

FieldTypeRequiredDescription
namestringYesSet name (max 200 chars)
descriptionstringNoDescription (max 500 chars)
isPublicbooleanNoEnable public access (default: false)

Example Request​

curl -X POST "https://api.synjar.com/api/workspaces/ws-123/instruction-sets" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "API Integration Guide",
"description": "Documents for integrating with our API",
"isPublic": true
}'

JavaScript​

const response = await fetch(
`https://api.synjar.com/api/workspaces/${workspaceId}/instruction-sets`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'API Integration Guide',
description: 'Documents for integrating with our API',
isPublic: true,
}),
}
);

const instructionSet = await response.json();
console.log(instructionSet.publicUrl);

Python​

import requests

response = requests.post(
f'https://api.synjar.com/api/workspaces/{workspace_id}/instruction-sets',
headers={'Authorization': f'Bearer {api_key}'},
json={
'name': 'API Integration Guide',
'description': 'Documents for integrating with our API',
'isPublic': True,
}
)

instruction_set = response.json()
print(instruction_set['publicUrl'])

Response​

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "API Integration Guide",
"description": "Documents for integrating with our API",
"isPublic": true,
"documentCount": 0,
"totalSizeBytes": 0,
"publicUrl": "https://app.synjar.com/s/550e8400-e29b-41d4-a716-446655440000",
"createdAt": "2025-12-30T10:00:00Z",
"updatedAt": "2025-12-30T10:00:00Z"
}

Get Instruction Set​

GET /api/instruction-sets/{id}

Returns detailed information about an Instruction Set, including its documents.

Example Request​

curl "https://api.synjar.com/api/instruction-sets/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer YOUR_API_KEY"

Response​

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "API Integration Guide",
"description": "Documents for integrating with our API",
"isPublic": true,
"publicUrl": "https://app.synjar.com/s/550e8400-e29b-41d4-a716-446655440000",
"createdAt": "2025-12-30T10:00:00Z",
"updatedAt": "2025-12-30T14:30:00Z",
"documents": [
{
"documentId": "doc-001",
"title": "Authentication Guide",
"sizeBytes": 12500,
"purpose": "INSTRUCTION",
"order": 0
},
{
"documentId": "doc-002",
"title": "API Reference",
"sizeBytes": 25000,
"purpose": "KNOWLEDGE",
"order": 1
}
],
"totalSizeBytes": 37500,
"documentCount": 2
}

Update Instruction Set​

PATCH /api/instruction-sets/{id}

Updates Instruction Set metadata. Supports optimistic locking to prevent concurrent edit conflicts.

Request Body​

FieldTypeRequiredDescription
namestringNoNew name (max 200 chars)
descriptionstringNoNew description (max 500 chars)
isPublicbooleanNoEnable/disable public access
expectedUpdatedAtISO 8601NoFor optimistic locking

Example Request​

curl -X PATCH "https://api.synjar.com/api/instruction-sets/550e8400" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Guide Name",
"isPublic": false,
"expectedUpdatedAt": "2025-12-30T14:30:00Z"
}'

JavaScript​

async function updateInstructionSet(id, updates, lastUpdatedAt) {
const response = await fetch(
`https://api.synjar.com/api/instruction-sets/${id}`,
{
method: 'PATCH',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
...updates,
expectedUpdatedAt: lastUpdatedAt,
}),
}
);

if (response.status === 409) {
const error = await response.json();
throw new Error(`Conflict: ${error.error.message}`);
}

return response.json();
}

Python​

def update_instruction_set(set_id, updates, last_updated_at=None):
payload = {**updates}
if last_updated_at:
payload['expectedUpdatedAt'] = last_updated_at

response = requests.patch(
f'https://api.synjar.com/api/instruction-sets/{set_id}',
headers={'Authorization': f'Bearer {api_key}'},
json=payload
)

if response.status_code == 409:
raise Exception(f"Conflict: {response.json()['error']['message']}")

return response.json()

Response​

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Updated Guide Name",
"description": "Documents for integrating with our API",
"isPublic": false,
"publicUrl": null,
"updatedAt": "2025-12-30T15:00:00Z"
}

Delete Instruction Set​

DELETE /api/instruction-sets/{id}

Permanently deletes an Instruction Set. Documents are NOT deleted (only removed from set).

Example Request​

curl -X DELETE "https://api.synjar.com/api/instruction-sets/550e8400" \
-H "Authorization: Bearer YOUR_API_KEY"

Response​

204 No Content

Document Management​

Add Document to Set​

POST /api/instruction-sets/{id}/documents

Adds a document to the Instruction Set. Only VERIFIED documents can be added.

Request Body​

FieldTypeRequiredDescription
documentIdstringYesDocument UUID to add

Example Request​

curl -X POST "https://api.synjar.com/api/instruction-sets/550e8400/documents" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"documentId": "doc-003"}'

JavaScript​

async function addDocumentToSet(setId, documentId) {
const response = await fetch(
`https://api.synjar.com/api/instruction-sets/${setId}/documents`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ documentId }),
}
);

if (!response.ok) {
const error = await response.json();
if (error.error.code === 'SIZE_LIMIT_EXCEEDED') {
throw new Error('Adding this document would exceed the 100 KB limit');
}
if (error.error.code === 'DOCUMENT_LIMIT_EXCEEDED') {
throw new Error('Maximum 20 documents allowed per set');
}
throw new Error(error.error.message);
}

return response.json();
}

Python​

def add_document_to_set(set_id, document_id):
response = requests.post(
f'https://api.synjar.com/api/instruction-sets/{set_id}/documents',
headers={'Authorization': f'Bearer {api_key}'},
json={'documentId': document_id}
)

if response.status_code == 400:
error = response.json()['error']
if error['code'] == 'SIZE_LIMIT_EXCEEDED':
raise Exception('Adding this document would exceed the 100 KB limit')
if error['code'] == 'DOCUMENT_LIMIT_EXCEEDED':
raise Exception('Maximum 20 documents allowed per set')

response.raise_for_status()
return response.json()

Response​

{
"documentId": "doc-003",
"title": "Error Handling Guide",
"sizeBytes": 8500,
"purpose": "INSTRUCTION",
"order": 2
}

Remove Document from Set​

DELETE /api/instruction-sets/{id}/documents/{documentId}

Removes a document from the set. The document itself is NOT deleted.

Example Request​

curl -X DELETE "https://api.synjar.com/api/instruction-sets/550e8400/documents/doc-003" \
-H "Authorization: Bearer YOUR_API_KEY"

Response​

204 No Content

Reorder Documents​

PATCH /api/instruction-sets/{id}/documents/reorder

Updates the order of documents in the set.

Request Body​

FieldTypeRequiredDescription
documentIdsstring[]YesDocument IDs in desired order

Example Request​

curl -X PATCH "https://api.synjar.com/api/instruction-sets/550e8400/documents/reorder" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"documentIds": ["doc-002", "doc-001", "doc-003"]}'

JavaScript​

async function reorderDocuments(setId, documentIds) {
const response = await fetch(
`https://api.synjar.com/api/instruction-sets/${setId}/documents/reorder`,
{
method: 'PATCH',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ documentIds }),
}
);

return response.json();
}

Python​

def reorder_documents(set_id, document_ids):
response = requests.patch(
f'https://api.synjar.com/api/instruction-sets/{set_id}/documents/reorder',
headers={'Authorization': f'Bearer {api_key}'},
json={'documentIds': document_ids}
)

response.raise_for_status()
return response.json()

Response​

{
"documents": [
{"documentId": "doc-002", "order": 0},
{"documentId": "doc-001", "order": 1},
{"documentId": "doc-003", "order": 2}
]
}

Public Access Endpoints​

These endpoints do NOT require authentication when the Instruction Set is public.

View Instruction Set (HTML)​

GET /s/{id}

Returns an HTML page with the combined content of all documents in the set.

Access Control​

  • Public sets (isPublic: true): Anyone with the link can view
  • Private sets (isPublic: false): Returns 404 Not Found

Example​

# Opens in browser
open "https://app.synjar.com/s/550e8400-e29b-41d4-a716-446655440000"

Response​

HTML page with:

  • Set name and description
  • Combined document content in order
  • Responsive styling for readability

Get Raw Content (Text)​

GET /s/{id}/raw

Returns plain text content of all documents, suitable for LLM context.

Example Request​

curl "https://app.synjar.com/s/550e8400-e29b-41d4-a716-446655440000/raw"

JavaScript​

async function getInstructionSetContent(publicUrl) {
const response = await fetch(`${publicUrl}/raw`);
if (!response.ok) {
throw new Error('Instruction set not found or not public');
}
return response.text();
}

// Usage with OpenAI
async function chatWithContext(question, instructionSetUrl) {
const context = await getInstructionSetContent(instructionSetUrl);

const response = await openai.chat.completions.create({
model: 'gpt-4',
messages: [
{
role: 'system',
content: `Use this context to answer questions:\n\n${context}`,
},
{ role: 'user', content: question },
],
});

return response.choices[0].message.content;
}

Python​

import requests
from openai import OpenAI

def get_instruction_set_content(public_url):
response = requests.get(f'{public_url}/raw')
response.raise_for_status()
return response.text

# Usage with OpenAI
def chat_with_context(question, instruction_set_url):
context = get_instruction_set_content(instruction_set_url)

client = OpenAI()
response = client.chat.completions.create(
model='gpt-4',
messages=[
{
'role': 'system',
'content': f'Use this context to answer questions:\n\n{context}',
},
{'role': 'user', 'content': question},
],
)

return response.choices[0].message.content

Response​

Content-Type: text/plain

# Authentication Guide

This guide covers how to authenticate with our API...

---

# API Reference

## Endpoints

### GET /api/users
...

Error Codes​

Instruction Set Errors​

CodeHTTPDescription
SIZE_LIMIT_EXCEEDED400Adding document would exceed 100 KB limit
DOCUMENT_LIMIT_EXCEEDED400Maximum 20 documents per set
DOCUMENT_NOT_VERIFIED400Only VERIFIED documents can be added
DOCUMENT_ALREADY_IN_SET409Document already exists in this set
CONFLICT409Concurrent edit detected (optimistic locking)
NOT_FOUND404Instruction set or document not found

Error Response Format​

{
"error": {
"code": "SIZE_LIMIT_EXCEEDED",
"message": "Adding this document would exceed the 100 KB size limit",
"details": {
"currentSize": 95000,
"documentSize": 8000,
"maxSize": 102400
},
"suggestion": "Remove some documents or choose a smaller document"
}
}

Conflict Error (409)​

When another user has modified the set:

{
"error": {
"code": "CONFLICT",
"message": "This set was modified by another user",
"details": {
"lastModifiedAt": "2025-12-30T15:00:00Z"
},
"suggestion": "Refresh the page to see the latest changes"
}
}

Rate Limits​

EndpointAuthenticatedPublic
List sets60/minN/A
Create/Update/Delete30/minN/A
Add/Remove documents60/minN/A
Reorder documents10/minN/A
View public set (HTML)N/A60/min per IP
Get raw contentN/A30/min per IP

Rate Limit Headers​

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1704110400

Response Fields Reference​

Instruction Set Object​

FieldTypeDescription
idstringUnique identifier (UUID)
namestringSet name
descriptionstringOptional description
isPublicbooleanWhether publicly accessible
publicUrlstringURL for public access (null if private)
documentCountnumberNumber of documents in set
totalSizeBytesnumberTotal content size in bytes
createdAtISO 8601Creation timestamp
updatedAtISO 8601Last modification timestamp
documentsarrayDocuments in order (only in GET /instruction-sets/:id)

Document Object​

FieldTypeDescription
documentIdstringDocument UUID
titlestringDocument title
sizeBytesnumberContent size in bytes
purposestringKNOWLEDGE or INSTRUCTION
ordernumberPosition in set (0-indexed)

Integration Examples​

Building a Custom Instructions Bot​

import OpenAI from 'openai';

const openai = new OpenAI();

async function createAssistantWithInstructions(instructionSetUrl) {
// Fetch the instruction set content
const response = await fetch(`${instructionSetUrl}/raw`);
const instructions = await response.text();

// Create an assistant with the instructions
const assistant = await openai.beta.assistants.create({
name: 'Custom Support Bot',
instructions: instructions,
model: 'gpt-4-turbo-preview',
});

return assistant;
}

Syncing Instructions to Claude​

import anthropic
import requests

def create_claude_message_with_instructions(question, instruction_set_url):
# Fetch instruction set content
response = requests.get(f'{instruction_set_url}/raw')
instructions = response.text

client = anthropic.Anthropic()

message = client.messages.create(
model='claude-3-opus-20240229',
max_tokens=1024,
system=instructions,
messages=[
{'role': 'user', 'content': question}
]
)

return message.content[0].text

See also​