The Wiro API
A way to read your agency’s clients, projects and team out of Wiro from other software — a spreadsheet, a client’s dashboard, an automation tool.
What this actually is
Wiro holds your data. Normally you look at it by signing in. The API is a second door: it lets a program ask Wiro for that data and get it back as text, without anyone signing in and clicking around.
You control that door with an API key — a long password you generate in Settings. Whoever holds the key can read your clients, projects and team. Nothing else, and nothing can be changed or deleted through it.
A real example
A client asks whether their project budgets can feed into their own finance dashboard automatically. You generate a key, send it to their developer with a link to this page, and they wire it up in an afternoon. From then on their dashboard updates itself, and you never export another spreadsheet by hand.
You probably don’t need it if
- Nobody has asked you for it. This is a thing you reach for when someone else requests your data in a format their software can read.
- You just want a spreadsheet once. Exporting from inside Wiro is faster.
- You want to push data into Wiro. This is read-only — it can only take data out.
Get a key
In Wiro, go to Settings → Integrations → Public REST API, type a label describing who it’s for (“Acme finance dashboard”), and press Generate.
- The key is shown once. Copy it somewhere safe before closing the box — Wiro stores only a fingerprint, so nobody can look it up for you later.
- Treat it like a password. Anyone holding it can read your client list. Send it the way you’d send a password, not in a public channel.
- One key per person or tool. That way you can revoke a single one without breaking everything else.
- Revoking is instant and permanent — the key stops working on the next request.
Hand this to your developer
Everything below is the technical part. The short version: three addresses, one header, JSON back.
Authentication
Send the key as a bearer token on every request. No key, or a revoked one, returns 401.
curl "https://wiro.ae/wapi/v1/clients" \ -H "Authorization: Bearer wiro_your_key_here"
What comes back
Always an object with data (the records) and pagination (where you are in the list). Records are ordered newest first.
{
"data": [ { "id": "…", "name": "Acme Corp", … } ],
"pagination": { "page": 1, "limit": 50, "total": 142, "pages": 3 }
}Paging
You get 50 records at a time. Pass ?page=2 for the next batch, and ?limit= to change the size — up to 100. Keep going until page reaches pages.
Rate limit
100 requests per minute per key. Going over returns 429; wait a moment and retry.
Clients
Every client in your agency, newest first.
| Field | Type | What it is |
|---|---|---|
id | id | Wiro's permanent ID for this client. Use it to match records between systems. |
name | string | The client's name as you typed it in Wiro. |
company | string or empty | Company name, if you recorded one. |
email | string or empty | Main email address on the client record. |
country | string or empty | Country, if set. |
industry | string or empty | Industry, if set. |
contact_name | string or empty | Day-to-day contact person at the client. |
contact_email | string or empty | That contact's email address. |
created_at | date | When the client was added to Wiro. |
Projects
Every project in your agency, newest first.
| Field | Type | What it is |
|---|---|---|
id | id | Wiro's permanent ID for this project. |
name | string | The project name. |
status | string | Where the project stands — the same status you see on the Projects page. |
budget | number or empty | Budget as a plain number, with no currency symbol. Null if you haven't set one. |
deadline | date or empty | Due date. Null if the project has no deadline. |
brief | string or empty | The project brief, as written. |
client_id | id or empty | Which client this belongs to — matches an `id` from Clients. Null for internal work. |
assigned_to | id or empty | Which team member owns it — matches an `id` from Team. Null if unassigned. |
created_at | date | When the project was created. |
Team
Your active team members, newest first. People you've removed are not included.
| Field | Type | What it is |
|---|---|---|
id | id | Wiro's permanent ID for this person. |
full_name | string or empty | Their name. Null if they haven't finished setting up their profile. |
email | string or empty | The email address they sign in with. |
role | string | Their permission level in Wiro — admin or member. |
department | string or empty | Department, if set. |
job_title | string or empty | Job title, if set. |
status | string | Always "active" here, since removed members are left out. |
avatar_url | string or empty | Link to their profile photo. Null if they haven't uploaded one. |
created_at | date | When they joined the agency. |
Pagination
The pagination object attached to every response.
| Field | Type | What it is |
|---|---|---|
page | integer | Which page you're looking at. |
limit | integer | How many records this page holds. |
total | integer | How many records exist in total. |
pages | integer | How many pages there are altogether. |
When something goes wrong
Errors come back as { "error": "…" } with one of these status codes.
| Code | Meaning | What to do |
|---|---|---|
401 | The key is missing, mistyped, or has been revoked. | Check the Authorization header, or generate a new key in Settings. |
429 | More than 100 requests in one minute on the same key. | Slow down and retry in a few seconds. |
500 | Something broke on Wiro's side. | Retry; if it persists, contact support@wiro.ae. |
The spec file
openapi.json is this page written for machines instead of people — an OpenAPI 3.1 document. Opening it in a browser looks like a wall of text, which is expected; it isn’t meant to be read directly.
Paste that URL into a tool and it configures itself:
- Postman or Insomnia — imports all three endpoints ready to call.
- Zapier, Make or n8n — the starting point for a custom connector.
- Code generators — turn it into a typed client in one command.
Questions? support@wiro.ae