Partner guide
This guide explains how to connect your own software to the SPLA API. The first part is in plain language and needs no technical background; the later parts have the exact calls for developers.
Address: https://cloudiq-spla.cleverpoc.com. Try it in your browser on the Try it page, or read
every call in the API reference.
In one minute
What is SPLA reporting? A hosting provider that rents out Microsoft software (for example Remote Desktop or Exchange) pays Microsoft per user per month. Microsoft calls this SPLA. Every month, before the 10th, the provider tells Microsoft through its reseller SoftwareOne how many licences it used the month before. That monthly list is the usage report. SoftwareOne's portal for it is called CloudIQ.
What is the problem? In CloudIQ the report is filled in by hand on a web page, line by line. There is no easy way to let your own administration system do it.
What does this service do? It is a translator between your software and CloudIQ. Your software asks simple questions ("what did we report for September?") or gives simple instructions ("start the October report and set Remote Desktop to 878"), and the service passes them on to CloudIQ in the way CloudIQ understands.
What does it never do?
- It never submits a report. Submitting is the moment SoftwareOne starts invoicing; a person always does that by pressing the final button in CloudIQ, after checking the draft.
- It never stores your password or secret. They are used once to log in and then forgotten.
- It never shows anything your own CloudIQ login may not see. It uses your login, so CloudIQ's own rights apply.
Is it from SoftwareOne? No. CleverIT built and runs it, on top of the official SoftwareOne Customer API. It is written so that it can later move to SoftwareOne or anywhere else without changes for you.
What does a month look like with it? Your software prepares the draft for last month in CloudIQ. It receives the CloudIQ link to that draft; ask your developer to show it to you, for example in your billing system or in an e-mail. You open it in CloudIQ as you do today, check it and press submit. The deadline of the 10th still applies: if the software has not prepared the draft in time, fill it in by hand as you do now. One simple rule: do not change the same draft by hand in CloudIQ while your software is working on it.
Does SoftwareOne know about it? CleverIT discussed it with SoftwareOne in October 2026; SoftwareOne's channel manager had no objection. It is not a SoftwareOne product: it uses SoftwareOne's own customer API with your own login, as any software of yours could. Using it does not change your SPLA contract or terms with SoftwareOne; questions about the contract go to SoftwareOne as before.
Advice for the monthly routine. Let the software prepare the draft early in the month (for example by the 5th) and let it notify the person who checks and submits, so there is time before the 10th.
Is this for you?
This service is a connection point for software, not a screen for people. It is useful when:
- you have your own administration or billing system that knows how many licences you used, and
- you have a developer, or a software supplier, who can connect that system to a web service.
Without one of those, keep filling in the report in CloudIQ by hand. The Try it page is for looking around and testing, not for the monthly work. As an estimate, a developer who has connected web services before needs about one or two days for a first working connection that reads the reports, plus the time to let your own system calculate the quantities. They can try everything on the demo first, with invented data and without any risk.
Getting access
Status today (October 2026). The service is public at https://cloudiq-spla.cleverpoc.com, from anywhere on
the internet; you do not have to register an address first. Reading real reports from CloudIQ works and has been
tested. Preparing drafts has so far only been tested on the demo with invented data, so on the real service it is
still switched off: your software can read everything and can try every change as a
dry run. It will be switched on after a first test with someone watching in CloudIQ.
- Try everything on the demo first, in the browser on the Try it page or from your own software.
- Connect with your own CloudIQ login (see Before you start). CloudIQ's own rights decide what you see; you can only ever see your own company.
- Please let CleverIT know that you use it, at support@cleverit.nl, with your company name. Then CleverIT can tell you about changes and when preparing drafts is switched on.
- Price and terms are not fixed yet. Ask CleverIT; nothing is charged without an agreement.
Words used in this guide
| Word | Meaning |
|---|---|
| API | A way for two computer programs to talk to each other, without a screen. Here: your software and this service. |
| Service, instance | This program running on a server. There are two: the real one (connected to CloudIQ) and the demo (invented data). |
| CloudIQ | SoftwareOne's (formerly Crayon's) customer portal, https://cloudiq.crayon.com |
| Organization | Your company in CloudIQ. It has a number, visible in CloudIQ addresses such as /home/4039837. |
| Agreement | One SPLA contract. Many providers have several, one per currency (EUR, GBP, DKK, ...). |
| Usage report | The monthly list of licences used, one report per month with lines on one or more agreements. |
| Line (row) | One product on one agreement with a quantity, for example "Office Standard on the GBP contract: 7". |
| Draft | A report that can still be changed. |
| Submitted | A report that has been sent to SoftwareOne. It can no longer be changed. |
| API client | A pair client id + client secret that you create in CloudIQ under API Integrations. It identifies your software. |
| Session token | A temporary key this service gives you after you log in. It replaces your password for at most 55 minutes. |
| Dry run | Trying a change without making it: the service checks everything and shows what it would send. |
Before you start
- A CloudIQ user for the connection. Our advice: a separate CloudIQ user just for this (for example
spla-integration@yourcompany.com), not a person's own login. It keeps working when someone leaves, and you can block it without blocking a colleague. It needs the right to see and edit Service Provider Reporting for your organization; CloudIQ's own rights decide what it can do through this service. Your CloudIQ administrator creates it. - An API client. Your CloudIQ administrator opens the menu, chooses API Integrations, then Add Client,
and gives it a clear name (for example
billing-system-spla). CloudIQ shows a client id and a client secret. Store the secret in your company password manager. Your developer also stores it in the protected settings of the system that connects (that system logs in every month); nobody else needs to see it. With option A (see below) the same goes for the password of the CloudIQ user for the connection. Whether SoftwareOne charges anything for an extra CloudIQ user: ask SoftwareOne. Only reading reports? Whether a CloudIQ role that can only view is enough has not been tested yet; ask your CloudIQ administrator, or test it on your own account. - The address of this service:
https://cloudiq-spla.cleverpoc.com(calls start with/v1/). - Optional: the demo, with invented data where every change is allowed. See Demo instance.
Log in
There are two ways. Both give you a session_token: a temporary key of at most 55 minutes that your software sends
with every question.
What happens with the password, in plain words. In option A your software sends the CloudIQ user name, password, client id and client secret to this service over an encrypted connection. The service passes them to SoftwareOne once, gets back a key that works for one hour, and forgets the password and secret immediately: they are never written to disk or to a log, so nobody at CleverIT can look them up later. The honest limit: a CleverIT administrator with full control of the server could in theory change the software. If you do not want to rely on that, use option B: your developer asks SoftwareOne for the one-hour key directly, and only that key reaches this service; your password never does. Option B is a little more work for the developer and is the safer choice. Our advice: ask your developer for option B; use option A only if B is not possible.
Option A: with your API client and user (most common)
curl -s -X POST https://cloudiq-spla.cleverpoc.com/v1/sessions \
-H 'Content-Type: application/json' \
-d '{"client_id": "...", "client_secret": "...", "username": "you@example.com", "password": "..."}'
The service asks CloudIQ for an access token with these four values (the OAuth2 "password" flow that SoftwareOne documents at https://apidocs.crayon.com/getting-started/authentication.html) and then forgets them.
Option B: with a CloudIQ access token you got yourself
If you prefer that your password never passes through this service, get the token directly from SoftwareOne and give only the token to this service:
curl -s -X POST https://api.crayon.com/api/v1/connect/token \
-u 'CLIENT_ID:CLIENT_SECRET' \
-d grant_type=password -d scope=CustomerApi \
--data-urlencode username=you@example.com --data-urlencode 'password=...'
# -> {"AccessToken": "eyJ...", "ExpiresIn": 3600, ...}
curl -s -X POST https://cloudiq-spla.cleverpoc.com/v1/sessions \
-H 'Content-Type: application/json' -d '{"access_token": "eyJ..."}'
The answer
{
"session_token": "spla_Q2xl...",
"token_type": "Bearer",
"expires_at": "2026-10-27T16:55:00Z",
"expires_in": 3300,
"idle_timeout_seconds": 1800,
"username": "you@example.com",
"organizations": [{"id": 4039837, "name": "Example Hosting BV"}],
"writes_enabled": false
}
Send the token with every other call:
curl -s https://cloudiq-spla.cleverpoc.com/v1/organizations -H 'Authorization: Bearer spla_Q2xl...'
A session ends after at most 55 minutes, after 30 minutes without use, when you log out
(DELETE /v1/sessions/current), or when the service restarts (for example after an update, which logs everyone
out). Then you get 401 session_expired: just log in again.
writes_enabled tells you whether this instance accepts changes (see Changing a draft).
A typical month
The steps below follow the monthly routine. ORG is your organization id from the login answer.
1. See which agreements count for the month
GET /v1/organizations/ORG/agreements?month=2026-10&valid_only=true
Agreements are renewed every few years; around a renewal both the old and the new one exist. valid_only=true
keeps only those valid in that month.
2. Look at last month's report
GET /v1/organizations/ORG/reports/by-month/2026-09
You get every line with agreement, product, quantity, unit price and line total, plus the total of the report.
GET /v1/organizations/ORG/reports lists all months; .../reports/REPORT_ID/export.csv gives a spreadsheet.
3. Start the new month (draft)
POST /v1/organizations/ORG/reports
{"month": "2026-10", "copy_previous": true}
This is the same as "Add Report" with "Copy Previous Month's Report" in CloudIQ: a draft with last month's lines at this month's prices.
4. Set the quantities
PATCH /v1/organizations/ORG/reports/REPORT_ID/rows/ROW_ID
{"quantity": 878}
Add a product to an agreement, or remove a line:
POST /v1/organizations/ORG/reports/REPORT_ID/rows {"agreement_id": 166738, "part_number": "021-08183", "quantity": 7}
DELETE /v1/organizations/ORG/reports/REPORT_ID/rows/ROW_ID
5. Check
GET /v1/organizations/ORG/reports/REPORT_ID/issues
shows the problems CloudIQ sees (for example a product that is not allowed on an agreement). Every report also has
a portal_url: open it to look at the draft in CloudIQ.
6. Submit - in CloudIQ, by a person
Open the portal_url, check the draft and submit it there. This service cannot submit, on purpose.
Changing a draft
- Only draft reports can be changed. A submitted report gives
409 report_not_editable. - Every change can be tried first with
?dry_run=true. The service checks the request, reads what it needs from CloudIQ and answers withwould_send: the call it would make (for adding or removing a line: the new line and a summary, because the full report it sends back is large). Nothing changes. A dry run also works on an instance where changes are switched off, so you can build and test against real data safely. - If the instance has changes switched off (
writes_enabled: false), a real change gives403 writes_disabled. Today changes are off for everyone; they will be switched on after a first test with someone watching in CloudIQ. - After a change you get the whole report back as it is now in CloudIQ, so you can check the result right away.
- Adding and removing lines work by sending the complete report back to CloudIQ with one line more or less,
because CloudIQ has no separate call for that. If someone edits the same draft in the CloudIQ portal at the
same moment, one of the two edits can be lost. Changing a quantity (
PATCH) does not have this problem. Advice: do not edit the same draft in the portal and through the API at the same time, and read the report again before you submit it.
All calls
The complete, machine-readable description is the OpenAPI specification. Load it into Postman, Insomnia or a code generator.
| Call | What it does |
|---|---|
POST /v1/sessions |
Log in (option A or B), get a session token |
GET /v1/sessions/current |
Your session: user, organizations, expiry |
DELETE /v1/sessions/current |
Log out |
GET /v1/organizations |
Organizations your login can see |
GET /v1/organizations/{org}/agreements |
SPLA agreements, optional month and valid_only |
GET /v1/organizations/{org}/agreements/{agreement}/prices |
Price list of an agreement, optional search, month |
GET /v1/organizations/{org}/reports |
All monthly reports (summary), optional year |
GET /v1/organizations/{org}/reports/by-month/{YYYY-MM} |
The report of one month, with lines |
GET /v1/organizations/{org}/reports/{report} |
One report with lines and status per agreement |
GET /v1/organizations/{org}/reports/{report}/issues |
Problems CloudIQ sees |
GET /v1/organizations/{org}/reports/{report}/export.csv |
Report as CSV |
POST /v1/organizations/{org}/reports |
Start a draft for a month |
PATCH /v1/organizations/{org}/reports/{report}/rows/{row} |
Change quantity or comment of a line |
POST /v1/organizations/{org}/reports/{report}/rows |
Add a line |
DELETE /v1/organizations/{org}/reports/{report}/rows/{row} |
Remove a line |
GET /healthz |
Is the service up (no login needed) |
What the data means
- Status of a report:
draft(can be changed),submitted(sent to SoftwareOne) orunknown(a state this service does not know; it never changes such a report). - Prices.
sales_unit_priceis what SoftwareOne charges you per unit; in CloudIQ this is in EUR for every agreement.purchase_unit_priceis the price in the currency of the agreement itself (for example GBP).line_total= quantity x sales unit price, rounded to cents.totalsis the total CloudIQ calculates. - Status per agreement (in a report):
not_reported,zero_usage_reported,usage_reportedorusage_and_zero_usage_reported, as SoftwareOne documents it. - Times are UTC (ISO 8601).
2026-10-12T18:30:26Zis 20:30 in the Netherlands in summer time. - Months are always written
YYYY-MM, for example2026-09.usage_monthis the month the licences were used, not the month the report was made.
When something goes wrong
Every error has the same shape:
{"error": {"code": "session_expired", "message": "The session token is unknown or has expired. Log in again.",
"request_id": "4f1c2a9b0d3e5f67"}}
| HTTP | code | What to do |
|---|---|---|
| 400 | invalid_request |
Fix the request; the message says what is wrong. |
| 400 | secret_in_url |
Never put passwords or tokens in the address; use the body or the Authorization header. |
| 401 | invalid_credentials |
CloudIQ did not accept the login. Check the four values (or the token). |
| 401 | unauthorized, session_expired |
Log in again. |
| 403 | writes_disabled |
Changes are off on this instance. Use ?dry_run=true, or ask CleverIT. |
| 403 | forbidden |
CloudIQ does not allow this for your user. Ask your CloudIQ administrator. |
| 404 | not_found |
It does not exist, or your login cannot see it. |
| 409 | report_not_editable |
The report is already submitted. |
| 409 | report_exists |
That month already has a report; details.report_id says which. |
| 409 | row_exists |
That product is already on that agreement; change details.row_id instead. |
| 413 | payload_too_large |
The request body is larger than 64 KB. |
| 415 | unsupported_media_type |
Send JSON with Content-Type: application/json. |
| 422 | agreement_not_found, agreement_not_valid, product_not_found |
The agreement or product does not fit this report. |
| 422 | upstream_rejected |
CloudIQ refused; details.upstream_message has its reason. |
| 429 | rate_limited |
Too many requests. Wait the seconds in the Retry-After header. |
| 502 | upstream_unexpected |
CloudIQ answered something the service cannot use: a change that is not visible afterwards (read the report again before retrying), or more than 5,000 results in one list. |
| 503 | upstream_unavailable, too_many_sessions |
Try again in a minute. |
| 500 | internal_error |
Our fault. Send us the request_id. |
Limits
| What | Limit (default) |
|---|---|
| Login attempts per IP address | 20 per 10 minutes (shared by all systems behind the same address) |
| Failed logins per user name | 5 per 15 minutes, then that user name waits |
| Requests per session | 120 per minute, at most 2 at the same time |
| Logins for one user name at the same time | 2 |
| Requests per IP address | 300 per minute; on the public address also at most 10 per second (bursts of 40) |
| Failed password logins for the whole service | 100 per 10 minutes (protection against password guessing); while reached, see below |
| Session length | at most 55 minutes (CloudIQ tokens last 60), and 30 minutes without use |
| Request body | 64 KB |
If someone tries to guess passwords. Two limits can then affect you, in plain words:
- Five wrong passwords for your user name, by anyone, make this service refuse that user name for 15 minutes. Your CloudIQ account itself is not locked.
- When very many wrong passwords arrive for the whole service, new user names are refused for a while. A user name that logged in successfully through this service in the last 60 days keeps working, so a monthly job that ran last month is fine. The very first login of a new user name can be refused while this lasts (try later), and logins with your own access token (option B) are never refused this way.
In both cases your software gets the answer 429 ("try again later") with the number of seconds to wait. Let it
try again later, or use option B. If it still fails close to the 10th, fill in the report by hand as before.
Keep it safe
- Treat the
session_tokenlike a password: it gives access to your SPLA data for up to 55 minutes. Keep it in memory, not in files or logs, and log out when your job is done. - Never put a password, secret or token in a URL. The service refuses such requests.
- Never switch off certificate checking in your software (for example
curl -korverify=False). The login sends your password and secret; without the check someone on the way could read them. - Use a separate CloudIQ API client per integration, so you can switch one off without affecting others.
- About the phone code (two-factor). The CloudIQ web portal asks for a code from your phone; SoftwareOne's API does not. Whoever has the client id, the client secret, a user name and its password can use the SoftwareOne API as that user without the phone code - with or without this service. That is how SoftwareOne built its API. What to do: create an API client only when you need one; keep the secret in your password manager and share it only with the person who sets up the connection; use a separate CloudIQ user for the connection; and delete the API client in CloudIQ (API Integrations) when you stop using it.
- What CleverIT keeps. For every request the service writes a line in its log: the time, the CloudIQ user name, the network address, which call, and for a change the old and new quantity. Never passwords, secrets or keys. The log is kept for 13 months, so that afterwards it can be shown who changed what. If your company needs a data processing agreement (GDPR) for this, ask CleverIT.
- More detail: Security.
Demo instance
The demo runs the same software against a fake CloudIQ with invented companies, agreements and prices. All
changes are allowed there and nothing reaches SoftwareOne. Its address is
https://cloudiq-spla.cleverpoc.com/demo: the same calls, with /demo in front (for example
POST /demo/v1/sessions). The easiest start is the Try it page, or choose the server /demo in the
API reference. Never enter your real CloudIQ login on the demo. Use only these logins - they are
fake and safe to share:
| Field | Value |
|---|---|
| client_id | demo-client |
| client_secret | demo-secret |
| username | demo@example.com |
| password | demo-password |
The demo company is organization 1000001 with reports for 2026-08 and 2026-09 (both submitted). Start a draft
for 2026-10 and try every call. Every login gets its own copy of the invented data: your changes are visible only
to you, and are forgotten after an hour (or when the demo restarts). One login keeps at most 40 reports; log in
again to start fresh.
Help
Contact CleverIT and mention the request_id of the call that went wrong. For questions about your SPLA
contracts, prices or the CloudIQ portal itself, contact SoftwareOne.