Overview
Every endpoint is served by the site itself under /api. There are three groups:
- Public APIs need no sign in: the partner directory, listing claims and password reset.
- Portal APIs power the partner and client portals. They need a signed in portal session and act only on the signed in organisation.
- AI Studio API is a published draft. It is not live yet; the shape may still change before release.
https://<your-site>/apiOn this site the APIs are under /api on the same domain.Requests and responses
- Send JSON with
Content-Type: application/json. Uploads usemultipart/form-datawith a singlefilefield. - Responses are JSON with camelCase names. Portal and claim responses carry a
successflag. - A request that is understood but refused, such as a wrong password, returns
200with"success": falseand anerrormessage. Check the flag, not only the status code. - Missing sign in returns
401, missing admin rights403, an unknown record404, malformed JSON400. - Dates are returned as display strings, for example
"Oct 29, 2026"or"2026-10-29", not ISO timestamps.
// refused but understood { "success": false, "error": "Invalid email or password." }
Authentication
Portal APIs use a secure, HTTP only session cookie that the browser keeps after a successful sign in. Sessions end after 8 hours without activity, and changing a password signs out every other session for that user.
- Call
POST /api/partner/portal/loginorPOST /api/client/portal/loginwithemailandpassword. - Send later requests from the same browser session. The cookie is sent automatically on the same site.
- Call
/logoutto end the session.
The portal APIs are designed for the portal pages on the same site. They do not send cross origin headers, so call them from your own server side code or from pages on the same domain.
Partner directory Public
Search and read the public partner listings. Only partners that are active and visible are returned.
/api/partner/loadSearch partners, paged| Query | Type | Notes |
|---|---|---|
page | int | Default 1 |
pageSize | int | 1 to 50, default 10 |
name | string | Part of the partner name |
country | string | Head office or other location |
level, qualification, industry | string | Values from /api/partner/filters |
Press Send to see a response.
Fictional example records in the exact shape the endpoint returns. The approval build does not call the live site.
/api/partner/filtersFilter optionsReturns levels, qualifications, industries and countries for building a search form. Each option carries the filterParameter value to send back to /load.
/api/partner/{slug}One partnerEverything in a search result plus profileDescription, whoWeAre, whyWeStandOut, contact details and projects. Returns 404 for an unknown slug.
Partner listing claims Public
/api/partner/claimAsk to manage a listingBody: partnerId (int), email, name, and optional jobTitle and involvement. The response is always the same thank you message, whether or not the details match, so the endpoint cannot be used to test which addresses exist. Claims are reviewed by staff in the back office.
Password reset Public
The same three steps exist for both portals: replace partner/portal with client/portal for the client portal.
| Endpoint | Purpose |
|---|---|
POST /api/partner/portal/forgot-password | Request a reset link for email. Always answers with the same message. |
GET /api/partner/portal/reset-password/validate?token= | Check a link before showing the form. Returns status: Valid, Expired, AlreadyUsed and so on. |
POST /api/partner/portal/reset-password | Set the new password: token, newPassword, confirmPassword. At least 8 characters with a letter and a number. |
Links are valid for 60 minutes and work once.
Partner portal Session
Base path /api/partner/portal. Reads are open to every user of the partner; changes to the profile, users, offices and projects need a partner admin.
| Area | Endpoints |
|---|---|
| Session | POST login POST logout GET me PUT change-password PUT change-details |
| Profile | GET profile PUT profile POST profile/logo GET industries PUT industries |
| Team | GET admins POST admins PUT admins/{id} DELETE admins/{id} GET team-members |
| Offices | GET offices POST offices PUT offices/{id} DELETE offices/{id} |
| Projects | GET projects POST projects PUT projects/{id} DELETE projects/{id} POST projects/{id}/image |
| Leads | GET leads GET leads/{id} POST leads PUT leads/{id} DELETE leads/{id} |
| Activity | GET sales GET websites POST websites PUT websites/{id} DELETE websites/{id} POST websites/{id}/screenshot GET audits GET audits/{id}/certificate GET surveys GET certifications GET activities/overview |
Images (logo, project image, website screenshot) accept JPG, PNG and WebP up to 5 MB. A deactivated partner can still sign in and read, but every change returns 403 with "partnerDeactivated": true.
Client portal Session
Base path /api/client/portal.
| Area | Endpoints |
|---|---|
| Session | POST login POST logout GET me POST change-password |
| Licences | GET licenses POST licenses/register |
| Evaluation keys | GET eval-keys POST eval-keys/request |
| Downloads | GET downloads |
AI Studio API Draft, not live
This is the planned interface for sending work to AI Studio from your own tools, such as a ticket system or a design tool. It is published early so you can plan; nothing here is callable yet, and names may change before release.
| Endpoint | Purpose |
|---|---|
POST /api/ai-studio/v1/attachments | Upload a screenshot, design export or HTML demo. Returns an attachment id. |
POST /api/ai-studio/v1/tasks | Describe a change. Returns 202 and a task id; the work runs on a branch and a staging copy. |
GET /api/ai-studio/v1/tasks/{id} | Status, steps, changed files, test results, preview link and usage. |
GET /api/ai-studio/v1/tasks/{id}/events | Live progress as server sent events. |
POST /api/ai-studio/v1/tasks/{id}/messages | Ask for more changes on the same task. |
POST /api/ai-studio/v1/tasks/{id}/approve | Approve the release. Only users with the approver role. |
POST /api/ai-studio/v1/tasks/{id}/reject | Close the task without releasing. |
POST /api/ai-studio/v1/releases/{id}/rollback | Restore the build that was live before a release. |
Authentication will use API keys created in the back office, sent as Authorization: Bearer <key>, each tied to a back office user and their roles.
curl -X POST https://<your-site>/api/ai-studio/v1/tasks \ -H "Authorization: Bearer $IBN_KEY" \ -H "Content-Type: application/json" \ -d '{"request":"Add a plan comparison block to /pricing","attachments":["att_7Q2"]}'
using var http = new HttpClient { BaseAddress = new Uri("https://your-site/") }; http.DefaultRequestHeaders.Authorization = new("Bearer", key); var res = await http.PostAsJsonAsync("api/ai-studio/v1/tasks", new { request = "Add a plan comparison block to /pricing", attachments = new[] { "att_7Q2" } }); var task = await res.Content.ReadFromJsonAsync<TaskCreated>();
const res = await fetch("/api/ai-studio/v1/tasks", { method: "POST", headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" }, body: JSON.stringify({ request: "Add a plan comparison block to /pricing", attachments: ["att_7Q2"] }) }); const { id, status } = await res.json();
// GET /api/ai-studio/v1/tasks/task_51F (draft shape) { "id": "task_51F", "status": "awaiting_approval", // queued, working, awaiting_approval, released, rejected, failed "branch": "ai-studio/plan-compare", "previewUrl": "https://staging.your-site/pricing", "files": [{ "path": "Views/Pricing/Index.cshtml", "added": 3, "removed": 19 }], "checks": [{ "name": "build", "result": "passed", "seconds": 41 }], "usage": { "tasksThisMonth": 38, "monthlyLimit": 400 } }
Webhooks Draft, not live
AI Studio will post task events to an address you register: task.awaiting_approval, task.released, task.failed and release.rolled_back. Each delivery will carry an X-IBN-Signature header, an HMAC SHA-256 of the body with your webhook secret, so you can check it came from your installation.
Widgets and templates
The site is an ASP.NET Core 8 MVC application. Editors build pages from widgets, sections and page templates; developers add new ones as ordinary view components in the solution, and AI Studio creates them the same way.
- Add a view component and its properties class under
Components/Widgets/<Name>/. - Register it with a unique identifier so it appears in the page builder.
- Put its view in
Components/Widgets/<Name>/Default.cshtmland its styles inwwwroot/css/widgets/. - Build, then add it to a page in the back office.
A full walkthrough with a sample widget will be added here when the extension guide is published.