API reference
WorkOSync exposes a small set of first-party JSON endpoints for authentication and contact, and runs on a headless ERPNext engine whose REST API holds every business record. This page documents the first-party endpoints exactly and gives a conceptual guide to the engine API.
API calls pass through the same request gate as pages: a tool-like user agent is refused with 403 (send a browser-style User-Agent), oversized bodies get 413, and repeated abuse bans the address. See Security.
First-party endpoints
POST /api/auth/signup
Creates a workspace and its Owner account, then sets the session cookie. Accepts JSON or a form body up to 8 KB.
POST /api/auth/signup
Content-Type: application/json
{
"name": "Khalid Al Falasi",
"email": "khalid@example.ae",
"company": "Falcon Trading LLC",
"password": "at least ten characters",
"country": "AE"
}| Response | Meaning |
|---|---|
201 { ok: true, user } | Workspace created; Set-Cookie: wos_session=… is included. |
400 { ok: false, error } | Validation failed. The message is generic by design; the only specific one is the ten-character password rule. |
Limits: five sign-ups per hour per address; name and company at least two characters; a URL in the name or company bans the address for an hour.
POST /api/auth/login
Authenticates and sets the session cookie. JSON or form body up to 4 KB.
POST /api/auth/login
Content-Type: application/json
{ "email": "you@company.ae", "password": "…" }| Response | Meaning |
|---|---|
200 { ok: true, user } | Signed in. user carries email, name, role and company. The response is cache-control: no-store. |
401 { ok: false, error } | Wrong credentials, throttled or locked out. The text is identical in every case. |
413 | Body larger than 4 KB. |
The optional fields _t (timing token) and website_url (honeypot) are what the HTML form sends; the JSON endpoint verifies the token only when supplied.
POST /api/auth/logout
Clears the session cookie and answers 303 See Other to /login.
POST /api/contact
Accepts the website contact form (name, email, company, message) up to 16 KB, saves the enquiry and sends the confirmation and notification emails. Five messages per ten minutes per address; a filled honeypot is banned but told { ok: true }.
The session cookie
wos_session is base64url(payload).base64url(HMAC-SHA256) with the user's email, name, role, company, issued-at and expiry (seven days). Send it back as a normal cookie on every request. It is httpOnly, so browser scripts cannot read it, and Secure in production.
The ERP engine API
Business records live in ERPNext, which exposes a resource-oriented REST API. Each kind of record is a DocType you can list, read, create and update over HTTP. The WorkOSync modules map onto these DocTypes:
| Module | DocType | Module | DocType |
|---|---|---|---|
| CRM & Leads | Lead | Accounting | Account, Journal Entry, GL Entry |
| Customers | Customer | Items & Services, Inventory | Item, Bin, Stock Ledger Entry |
| Suppliers | Supplier, Purchase Invoice | Projects | Project, Task, Timesheet |
| Quotations | Quotation | HR & Payroll | Employee, Salary Slip |
| Sales & Orders | Sales Order, Purchase Order | Contracts | Contract |
| Invoicing | Sales Invoice | Notes, Reminders | Note, ToDo |
| Payments | Payment Entry | Reports | Query and script reports by name |
Authentication
Engine requests authenticate with an API key and secret issued for a user, sent in the Authorization header. Keys are generated on the server and identify a specific user, so API actions respect that user's role. Keep the secret confidential and rotate it if it is ever exposed.
Authorization: token <api_key>:<api_secret>
Content-Type: application/jsonReading resources
# List recent sales invoices
GET /api/resource/Sales%20Invoice?limit_page_length=20
# Read one customer by name
GET /api/resource/Customer/Emirates%20Steel%20Co.{
"data": {
"name": "Emirates Steel Co.",
"tax_id": "100xxxxxxxxxxxx3",
"default_currency": "AED"
}
}Creating a record
A create request posts JSON describing the new record. WorkOSync itself creates invoices this way, adding the VAT 5% - FT tax line and submitting the document so it posts to the ledger.
POST /api/resource/Sales%20Invoice
{
"customer": "Emirates Steel Co.",
"currency": "AED",
"items": [
{ "item_code": "ST-COIL-04", "qty": 120, "rate": 340 }
]
}Reports
The Reports module runs ERPNext query reports by name with preset filters, for example Accounts Receivable Summary aged by due date at 30/60/90 days, or Profit and Loss Statement for the fiscal year. The result's columns and rows are rendered as-is.
Good practice
- Treat API keys like passwords. Store them server-side, never in client code.
- Handle pagination when listing; do not assume every record fits in one response.
- Respect rate limits and back off on errors; the platform throttles abusive traffic.
- Let the engine compute tax and totals rather than posting your own VAT figures.
- Send a real
User-Agent; raw HTTP libraries are refused by the request gate.
If you want an answer rather than a data feed, Ask AI can often replace a custom integration.