Build powerful integrations with Nuto Office. Create, edit, convert documents and enable real-time collaboration — all through a simple REST API.
# 1. Get your API token curl -X POST https://nuto.thamming.com/api/auth/token \ -H "Content-Type: application/json" \ -d '{ "apiKey": "your-api-key", "secret": "your-secret" }' # 2. Create a document curl -X POST https://nuto.thamming.com/api/documents \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "title": "My Report", "type": "Docs", "format": "DOCX" }' # Response: { "id": "a1b2c3...", "title": "My Report" }
Base URL: https://nuto.thamming.com/api
API Key management, JWT token generation and validation
3 endpointsCRUD operations, upload, download, and format conversion
8 endpointsVersion history and point-in-time restore
2 endpoints16 pre-built templates for Docs, Sheet, and Slide
2 endpointsReal-time session management and presence indicators
2 endpointsGenerate scoped embed config for iframe integration
1 endpointAuthenticate in 3 simple steps. Tokens expire after 60 minutes by default.
Register an API client to get your key and secret
Exchange API key + secret for a bearer token
Add the token to your request headers
# Step 1: Create API Key (one-time setup) curl -X POST https://nuto.thamming.com/api/auth/api-keys \ -H "Content-Type: application/json" \ -d '{ "name": "My App", "permissions": ["documents:read", "documents:write", "collaboration:join"] }' # Response: { "apiKey": "nuto_ak_xxx", "secret": "nuto_sk_xxx" } # *** Save the secret — it won't be shown again *** # Step 2: Generate JWT Token curl -X POST https://nuto.thamming.com/api/auth/token \ -H "Content-Type: application/json" \ -d '{ "apiKey": "nuto_ak_xxx", "secret": "nuto_sk_xxx" }' # Response: { "token": "eyJhbG...", "expiresAt": "2026-01-15T11:30:00Z" } # Step 3: Use the token curl https://nuto.thamming.com/api/documents \ -H "Authorization: Bearer eyJhbG..."
// Step 1: Create API Key (one-time) const keyRes = await fetch('https://nuto.thamming.com/api/auth/api-keys', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'My App', permissions: ['documents:read', 'documents:write'] }) }); const { apiKey, secret } = await keyRes.json(); // Step 2: Get JWT Token const authRes = await fetch('https://nuto.thamming.com/api/auth/token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ apiKey, secret }) }); const { token } = await authRes.json(); // Step 3: Use the token const docs = await fetch('https://nuto.thamming.com/api/documents', { headers: { 'Authorization': `Bearer ${token}` } }).then(r => r.json());
import requests # Step 1: Create API Key (one-time) key_res = requests.post( "https://nuto.thamming.com/api/auth/api-keys", json={ "name": "My App", "permissions": ["documents:read", "documents:write"] } ) api_key = key_res.json()["apiKey"] secret = key_res.json()["secret"] # Step 2: Get JWT Token auth_res = requests.post( "https://nuto.thamming.com/api/auth/token", json={"apiKey": api_key, "secret": secret} ) token = auth_res.json()["token"] # Step 3: Use the token headers = {"Authorization": f"Bearer {token}"} docs = requests.get( "https://nuto.thamming.com/api/documents", headers=headers ).json()
Click an endpoint to see request/response details and code examples.
| Field | Type | Description |
|---|---|---|
| namerequired | string | API client name (1-200 chars) |
| permissionsrequired | string[] | e.g. documents:read, documents:write, collaboration:join |
| Field | Type | Description |
|---|---|---|
| id | uuid | API Client ID |
| name | string | Client name |
| apiKey | string | Generated API key |
| secret | string | Secret (shown once only) |
| permissions | string[] | Assigned permissions |
| createdAt | datetime | Creation timestamp |
| Field | Type | Description |
|---|---|---|
| apiKeyrequired | string | Your API key |
| secretrequired | string | Your API secret |
| Field | Type | Description |
|---|---|---|
| token | string | JWT bearer token |
| expiresAt | datetime | Expiration time (default 60 min) |
| Header | Value | Description |
|---|---|---|
| Authorizationrequired | Bearer {token} | JWT token |
| Field | Type | Description |
|---|---|---|
| clientId | string | Client ID from token |
| name | string | Client name |
| permissions | string[] | Assigned permissions |
| isValid | boolean | Token validity |
| expiresAt | datetime? | Expiration time |
| Field | Type | Description |
|---|---|---|
| titlerequired | string | Document title (1-500 chars) |
| typerequired | DocType | Docs | Sheet | Slide |
| formatrequired | DocFormat | DOCX, XLSX, PPTX, etc. |
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "My Report",
"type": "Docs",
"format": "DOCX",
"createdAt": "2026-01-15T10:30:00Z",
"updatedAt": "2026-01-15T10:30:00Z",
"fileSize": 0
}
| Param | Type | Description |
|---|---|---|
| typeoptional | DocType | Filter: Docs, Sheet, Slide |
| searchoptional | string | Free-text search on title |
| sortByoptional | string | Field to sort by |
| sortDescendingoptional | bool | Default: true |
| skipoptional | int | Offset, default: 0 |
| takeoptional | int | Limit, default: 20 |
| Param | Type | Description |
|---|---|---|
| idrequired | uuid | Document ID |
| Field | Type | Description |
|---|---|---|
| titleoptional | string | New title (max 500 chars) |
| jsonContentoptional | string | Editor JSON content |
A version snapshot is created automatically on each update.
Soft-deletes the document. Data is preserved and can potentially be recovered.
multipart/form-data — Supports DOCX, XLSX, PPTX, PDF, TXT, CSV, MD, HTML, RTF, ODT, ODS, ODP
curl -X POST https://nuto.thamming.com/api/documents/upload \ -H "Authorization: Bearer <token>" \ -F "file=@report.docx"
| Param | Type | Description |
|---|---|---|
| formatoptional | DocFormat | Target format (original if omitted) |
Returns binary file stream with Content-Type and Content-Disposition headers.
| Field | Type | Description |
|---|---|---|
| targetFormatrequired | DocFormat | e.g. PDF, CSV, HTML |
Original document remains unchanged. Returns converted file as download.
| Field | Type | Description |
|---|---|---|
| versions[].id | uuid | Version ID |
| versions[].versionNumber | int | Version sequence number |
| versions[].createdAt | datetime | Creation timestamp |
| versions[].createdBy | string | Author |
| versions[].changeDescription | string? | Description of changes |
Current state is automatically saved as a new version before restoring. No data is lost.
Returns 16 templates across categories: Basic, Business, Finance, Education, Personal
| Field | Type | Description |
|---|---|---|
| templates[].id | string | Template ID (e.g. doc-report) |
| templates[].name | string | Display name |
| templates[].type | string | Docs, Sheet, Slide |
| templates[].category | string | Template category |
| Field | Type | Description |
|---|---|---|
| templateIdrequired | string | Template ID from list endpoint |
| titleoptional | string | Custom title (uses template default if omitted) |
| Field | Type | Description |
|---|---|---|
| documentIdrequired | uuid | Document to join |
| userIdrequired | string | Unique user ID |
| userNamerequired | string | Display name (1-100 chars) |
| Field | Type | Description |
|---|---|---|
| sessionId | uuid | Session ID |
| userColor | string | Assigned hex color |
| activeUsers | array | Currently active users |
| Field | Type | Description |
|---|---|---|
| documentId | uuid | Document ID |
| activeUserCount | int | Number of active users |
| activeUsers | array | User details with colors |
| Field | Type | Description |
|---|---|---|
| documentIdrequired | uuid | Document to embed |
| permissionsrequired | string[] | view, edit, comment |
| Field | Type | Description |
|---|---|---|
| url | string | Embed iframe URL |
| token | string | Scoped JWT (24h expiry) |
| permissions | string[] | Granted permissions |
| expiresAt | datetime | Token expiration |
Real-time collaboration powered by Yjs CRDT over SignalR. Connect to wss://nuto.thamming.com/hubs/document
Join a document room for receiving/sending changes
Leave a document room
Send Yjs binary update (Base64 encoded)
Request full Yjs state for initial sync
Broadcast cursor position and presence
Get list of connected users
ReceiveUpdate, UserJoined, UserLeft, and more
// Connect to SignalR hub import * as signalR from '@microsoft/signalr'; const connection = new signalR.HubConnectionBuilder() .withUrl('https://nuto.thamming.com/hubs/document') .withAutomaticReconnect() .build(); await connection.start(); // Join a document room await connection.invoke( 'JoinDocument', 'doc-id-here', // documentId 'John Doe', // userName (optional) '#FF6B6B' // userColor (optional) ); // Listen for other users joining connection.on('UserJoined', (connId) => { console.log(`User joined: ${connId}`); });
Upload, download, and convert between all major office document formats.
Choose the integration method that fits your stack.
import { NutoEditor } from '@nutooffice/sdk'; const editor = new NutoEditor('editor-container', { serverUrl: 'https://nuto.thamming.com', documentId: 'your-document-id', type: 'docs', token: 'your-jwt-token', callbacks: { onReady: () => console.log('Ready!'), onSave: (data) => console.log('Saved'), }, });
# Create doc, upload, convert — in 3 calls curl -X POST .../api/documents \ -H "Authorization: Bearer <token>" \ -d '{"title":"Report","type":"Docs","format":"DOCX"}' curl -X POST .../api/documents/upload \ -H "Authorization: Bearer <token>" \ -F "file=@report.docx" curl -X POST .../api/documents/{id}/convert \ -d '{"targetFormat":"PDF"}' -o report.pdf
<!-- Embed in any web page --> <iframe src="https://nuto.thamming.com/embed/docs/{id} ?token={jwt}" width="100%" height="600" frameborder="0" allowfullscreen ></iframe> <!-- Permissions: view, edit, comment --> <!-- Token expires after 24 hours -->