Python SDK for SurfaceDocs - Save LLM-generated documents
Project description
SurfaceDocs Python SDK
Save LLM-generated documents to SurfaceDocs.
Installation
pip install surfacedocs
Quick Start
from surfacedocs import SurfaceDocs, DOCUMENT_SCHEMA, SYSTEM_PROMPT
from openai import OpenAI
# Initialize clients
openai = OpenAI()
docs = SurfaceDocs(api_key="sd_live_...")
# Generate a document with your LLM
response = openai.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": "Document our REST API authentication flow"},
],
response_format={
"type": "json_schema",
"json_schema": {
"name": "surfacedocs_document",
"schema": DOCUMENT_SCHEMA,
},
},
)
# Save to SurfaceDocs
result = docs.save(response.choices[0].message.content)
print(result.url) # https://app.surfacedocs.dev/d/abc123
What's Included
The SDK provides three exports:
| Export | Type | Purpose |
|---|---|---|
DOCUMENT_SCHEMA |
dict | JSON schema for LLM structured output |
SYSTEM_PROMPT |
str | Instructions for LLM to generate documents |
SurfaceDocs |
class | HTTP client to save documents |
API Reference
SurfaceDocs
from surfacedocs import SurfaceDocs
# Initialize with API key
client = SurfaceDocs(api_key="sd_live_...")
# Or use environment variable
# export SURFACEDOCS_API_KEY=sd_live_...
client = SurfaceDocs()
save(content, folder_id=None)
Save a document from LLM output.
# From JSON string
result = client.save(response.choices[0].message.content)
# From dict
result = client.save({
"title": "My Document",
"blocks": [{"type": "paragraph", "content": "Hello world"}]
})
# To specific folder
result = client.save(content, folder_id="folder_abc123")
save_raw(title, blocks, folder_id=None, metadata=None)
Save a document with explicit parameters.
result = client.save_raw(
title="API Documentation",
blocks=[
{"type": "heading", "content": "Authentication", "metadata": {"level": 1}},
{"type": "paragraph", "content": "Use Bearer tokens for auth."},
{"type": "code", "content": "curl -H 'Authorization: Bearer ...'", "metadata": {"language": "bash"}},
],
metadata={"source": "doc-generator", "version": "1.0"},
)
SaveResult
Both methods return a SaveResult:
result.id # "doc_abc123"
result.url # "https://app.surfacedocs.dev/d/doc_abc123"
result.folder_id # "folder_xyz"
DOCUMENT_SCHEMA
JSON schema dict for LLM structured output. Pass directly to your LLM provider.
SYSTEM_PROMPT
System prompt string to instruct LLMs on document format.
from surfacedocs import SYSTEM_PROMPT
messages = [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": "Document the login flow"},
]
Block Types
Documents are composed of blocks:
| Type | Description | Metadata |
|---|---|---|
heading |
Section header | level (1-6) |
paragraph |
Body text | - |
code |
Code block | language (optional) |
list |
Bullet/numbered list | listType ("bullet" or "ordered") |
quote |
Block quote | - |
table |
Markdown table | - |
image |
Image | url (required), alt (optional) |
divider |
Horizontal rule | - |
Text content supports inline markdown: **bold**, *italic*, `code`, [link](url)
Error Handling
from surfacedocs import SurfaceDocs, SurfaceDocsError, AuthenticationError, ValidationError
try:
result = client.save(content)
except AuthenticationError:
print("Invalid API key")
except ValidationError as e:
print(f"Invalid document: {e}")
except SurfaceDocsError as e:
print(f"API error: {e}")
Environment Variables
# API key (alternative to passing in code)
export SURFACEDOCS_API_KEY=sd_live_...
The SDK auto-detects environment from API key prefix:
sd_live_*→ Productionsd_test_*→ Development
Examples
OpenAI
from surfacedocs import SurfaceDocs, DOCUMENT_SCHEMA, SYSTEM_PROMPT
from openai import OpenAI
openai = OpenAI()
docs = SurfaceDocs()
response = openai.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": "Write documentation for user authentication"},
],
response_format={
"type": "json_schema",
"json_schema": {"name": "document", "schema": DOCUMENT_SCHEMA},
},
)
result = docs.save(response.choices[0].message.content)
print(f"Saved: {result.url}")
Anthropic
Using Claude's structured outputs with tool use:
from surfacedocs import SurfaceDocs, DOCUMENT_SCHEMA, SYSTEM_PROMPT
import anthropic
client = anthropic.Anthropic()
docs = SurfaceDocs()
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
system=SYSTEM_PROMPT,
messages=[
{"role": "user", "content": "Write documentation for user authentication"},
],
tools=[{
"name": "create_document",
"description": "Create a structured document",
"input_schema": DOCUMENT_SCHEMA,
}],
tool_choice={"type": "tool", "name": "create_document"},
)
tool_use = next(b for b in response.content if b.type == "tool_use")
result = docs.save(tool_use.input)
print(f"Saved: {result.url}")
Google Gemini
Using Gemini's structured output with JSON schema:
from surfacedocs import SurfaceDocs, DOCUMENT_SCHEMA, SYSTEM_PROMPT
import google.generativeai as genai
genai.configure(api_key="...")
docs = SurfaceDocs()
model = genai.GenerativeModel(
model_name="gemini-2.0-flash",
system_instruction=SYSTEM_PROMPT,
generation_config=genai.GenerationConfig(
response_mime_type="application/json",
response_schema=DOCUMENT_SCHEMA,
),
)
response = model.generate_content("Write documentation for user authentication")
result = docs.save(response.text)
print(f"Saved: {result.url}")
Manual Document
from surfacedocs import SurfaceDocs
docs = SurfaceDocs()
result = docs.save_raw(
title="Meeting Notes",
blocks=[
{"type": "heading", "content": "Action Items", "metadata": {"level": 1}},
{"type": "list", "content": "- Review PR #123\n- Update docs", "metadata": {"listType": "bullet"}},
{"type": "divider", "content": ""},
{"type": "paragraph", "content": "Next meeting: Monday 10am"},
],
metadata={"source": "meeting-bot"},
)
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file surfacedocs-0.1.0.tar.gz.
File metadata
- Download URL: surfacedocs-0.1.0.tar.gz
- Upload date:
- Size: 31.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc52192045d7001f3a8757f6e7654bd33d12b9d981ac16e9c1acd4b6570af0d5
|
|
| MD5 |
12074d219e38a4a2aec572a1df1d5a84
|
|
| BLAKE2b-256 |
79341252ef373aa5243836c63f1bdbcfc5b78073fddd4bd2fdbbd7e18e81857e
|
File details
Details for the file surfacedocs-0.1.0-py3-none-any.whl.
File metadata
- Download URL: surfacedocs-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b0a0663b167c7d186054130003330a1e893d061c65a0db6d31a219c3ce3c67e
|
|
| MD5 |
4b70a70467534f93bf05ae1594e5c6aa
|
|
| BLAKE2b-256 |
8a866bc4d77739d10725d19a8073a5f5c97ba7a9b29c11460d2dd85d33f27b84
|