Upload files, read spreadsheet-based plan data, and manage touchpoints programmatically. Designed for internal tools, CRM integrations, workflow automation, and partner platforms like Salesforce.
https://api.plansync.aiAll API requests (except /health) require an API key in the X-API-Key header.
Getting your API key
Key management
| Multiple keys | You can create multiple API keys, each with a unique name |
| Revocation | Keys can be revoked at any time — immediate and permanent |
| Expiration | API keys do not expire automatically |
| Rotation | Create new key first, update integrations, then revoke old key |
Get your first successful API call in under two minutes.
Step 1 — Health check (no auth required)
Step 2 — List spreadsheets
Step 3 — Fetch real data
Understand the key resources and how they work before diving into endpoints.
year query param selects the database table. reporting_year in the body is the stored value.user_id needed.GET /api/v1/spreadsheetsGET /api/v1/spreadsheets/{name}/schema?year=2025GET /api/v1/spreadsheets/{name}/data?year=2025data array in your applicationPOST /api/v1/files/upload with file, company_name, document_typefile_location and metadataPOST /api/v1/touchpoints?year=2025GET /api/v1/touchpoints?year=2025PUT /api/v1/touchpoints/{id}?year=2025DELETE /api/v1/touchpoints/{id}?year=2025Check if the API is running. No authentication required.
Example request
Success response 200
Returns the names of all available spreadsheet types.
Example request
Success response 200
Fetch rows from a specific spreadsheet.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
sheet_name | path | string | Yes | Spreadsheet name, URL-encode spaces |
year | query | integer | Yes | Reporting year |
role | query | string | No | Filter: admin, tpa editor, recordkeeper, advisor, plan sponsor |
assigned_clients | query | string | No | JSON array of client names |
Example request
Success response 200
Error responses
| Status | When |
|---|---|
400 | Invalid spreadsheet name |
404 | No data table for the specified year |
Upload a document to storage (multipart/form-data).
Request body (form-data)
| Field | Type | Required | Description |
|---|---|---|---|
file | file | Yes | The file to upload |
company_name | string | Yes | Company name |
document_type | string | Yes | E.g. Plan Document, Amendment, Report |
.pdf .doc .docx .xls .xlsx .jpg .jpeg .png — Max 50 MB. Duplicate filenames overwrite.Example request
Success response 200
Error responses
| Status | When |
|---|---|
400 | Unsupported file type or exceeds 50 MB |
List all files for the authenticated user.
Example request
Success response 200
Download a file from storage.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
filename | path | string | Yes | Exact filename from file list |
Example request
Returns binary file stream with Content-Disposition: attachment.
Permanently delete a file.
Example request
Success response 200
Client interaction records. All endpoints require a year query parameter. Each touchpoint has a UUID (unid) used for update and delete.
Create a new touchpoint record.
Request body (JSON)
| Field | Type | Required | Description |
|---|---|---|---|
company_name | string | Yes | Company/client name |
touchpoints | string | Yes | Description of interaction |
reporting_quarter | string | Yes | Q1, Q2, Q3, Q4, or All |
reporting_year | string | Yes | Year value, e.g. "2025" |
stakeholders | string | No | Plan Sponsor, TPA, Recordkeeper, etc. |
date | string | No | YYYY-MM-DD (defaults to today) |
time_spent | number | No | Minutes spent |
include_in_annual_review_report | string | No | "Yes" or "No" (default "No") |
Example request
Success response 200
unid in the response is the ID you use for update and delete operations.Retrieve touchpoints with optional filtering.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
year | integer | Yes | Reporting year table |
company_name | string | No | Filter by company (exact match) |
quarter | string | No | Q1, Q2, Q3, Q4 |
stakeholder | string | No | Filter by stakeholder |
Example request
Success response 200
Update an existing touchpoint. Only include fields you want to change.
Example request
Success response 200
Permanently delete a touchpoint.
Example request
Success response 200
Error format
Validation errors (422) include field-level details in detail as an array.
HTTP status codes
| Status | Meaning | When |
|---|---|---|
200 | Success | Request completed |
400 | Bad Request | Invalid parameters or values |
401 | Unauthorized | Missing or invalid API key |
403 | Forbidden | Access denied |
404 | Not Found | Resource doesn't exist |
422 | Unprocessable Entity | Validation failure |
429 | Too Many Requests | Rate limit exceeded |
500 | Server Error | Unexpected failure |
Rate limits & constraints
| Constraint | Value |
|---|---|
| Rate limit | 60 requests/minute per API key (rolling window) |
| File size | 50 MB maximum |
| File types | .pdf, .doc, .docx, .xls, .xlsx, .jpg, .jpeg, .png |
| Timeout | 120 seconds server-side |
| Pagination | Not supported — all records returned in one response |
Retry guidance
| Status | Retry? | Strategy |
|---|---|---|
429 | Yes | Wait 60s, then retry |
500 | Yes | Exponential backoff (1s, 2s, 4s — max 3 tries) |
4xx | No | Fix the request |
Complete examples for Python, JavaScript, and Salesforce. See the full API reference for all endpoints.
Salesforce integration uses Named Credentials for secure API key storage. Never hardcode keys in Apex.
https://api.plansync.aiX-API-Key custom headercallout:PlanSyncX-API-Key header and confirm the key is active at app.plansync.ai.%20. Call GET /api/v1/spreadsheets to see the exact names.?year=2025 reads from the 2025 reporting table. The reporting_year body field is the stored value on the record.touchpoint_id, and the same value appears as unid in response objects.- Initial public API release
- Spreadsheet data access (read-only)
- File upload, download, list, and delete
- Touchpoint CRUD operations
- API key authentication with rate limiting
- Automatic user identity from API key
Versioning policy
- Version in URL path:
/api/v1/... - 90 days notice before breaking changes
- New fields may be added without version change — ignore unknown fields
- Breaking changes use a new prefix (e.g.
/api/v2/...)