Support connector API
A reseller can connect its own support system. Every support request from one of its customers is then also created there, and replies and closes can travel both ways. You implement four small HTTP endpoints; SphereHarness calls them.
Before anything is sent
The customer is told, in the desktop agent, who will receive the request (your company name and the host of your API), exactly what is sent, and a link to your privacy notice, and must say yes. If they decline, the request stays in your SphereHarness support queue only. The request is always kept in your SphereHarness queue as well, so nothing is lost when your system is down.
Calling you
- Address.
https://only, a public host. Private and internal addresses are refused. - Authentication.
<Header>: <Prefix> <key>. The default isAuthorization: Bearer <key>; you choose another header (for exampleX-Api-Key, with no prefix) in the form. - Where from. Our server's address is
20.170.9.91if you allow-list. TheUser-AgentisSphereWorks-Connector/1. - Body. JSON,
Content-Type: application/json. Timeout 15 seconds. - Idempotency. Every write carries an
Idempotency-Keyheader. Repeating a key must return the first result and change nothing. We repeat on timeouts and 5xx answers.
Endpoints you implement
All paths are appended to the address you entered ({base}).
GET {base}/ping
Return 200 and, if you like, { "ok": true, "name": "Acme Service Desk" }. Used by Test connection.
POST {base}/tickets
Create a request. Return 201 with { "id": "T-1234" } (the id is a string or a number; url and status are optional).
{
"source": "sphereworks",
"ticketId": 4711,
"subject": "Fillet fails on a shelled body",
"description": "What the customer wrote.",
"requester": { "name": "Ada Lovelace", "email": "ada@customer.example", "organisation": "Customer AS" },
"product": { "cad": "Inventor 2025", "clientVersion": "1.3.9.0" },
"createdAt": "2026-10-25T09:00:00.0000000Z",
"attachments": [
{ "fileName": "diagnostics.zip", "bytes": 482113, "contentType": "application/zip",
"url": "https://.../api/v1/support/connector/attachments/..." }
],
"test": false
}
product.cad and product.clientVersion are null when an older add-in sent no version. An attachment url is a signed download link, valid 7 days; you receive a link, never the file bytes. test: true is sent by Test connection: answer 201 and discard the request.
POST {base}/tickets/{id}/comments
Only when the reseller ticked Also send replies and closes. {id} is the id you returned. Return 201 with { "id": "c-9" }.
{
"ticketId": 4711,
"messageId": 9120,
"author": { "kind": "user", "name": "Ada Lovelace" },
"text": "It also happens with a 2 mm shell.",
"createdAt": "2026-10-25T09:30:00.0000000Z",
"attachments": []
}
author.kind is user (the customer), reseller (your staff in the SphereHarness portal) or admin.
PATCH {base}/tickets/{id}
Only with Also send replies and closes. Body { "status": "closed" } or { "status": "reopened" } (a customer replies on a closed request). Return 200.
GET {base}/tickets/{id} (optional)
Return { "id": "T-1234", "status": "open", "updatedAt": "..." }.
Errors and what we do
| You answer | We do |
|---|---|
| 2xx | Done. The request shows as synced. |
| 401 or 403 | The connector is marked failing, paused for 10 minutes, and your staff are notified. Fix the key and save the form. |
429 (with Retry-After) | Treated as temporary; retried later. |
| 5xx, timeout, no answer | One immediate retry, then retried every 5 minutes for 24 hours. 5 failures in a row pause the connector for 10 minutes. |
| Other 4xx (400, 404, 409) | Logged, shown in the call list on your Support page, and retried like a temporary error until the 24 hours are up. The request stays in your SphereHarness queue. |
Errors should be JSON, { "error": "code", "message": "what went wrong" }; the message is shown to you (never to the customer). We call you at most 60 times a minute.
Calling us: the webhook (optional)
To bring your staff's replies and closes back into the customer's thread, enter a webhook signing secret in the form and send:
POST https://<your SphereHarness host>/api/v1/support/connector/webhook/<your reseller slug>
X-SphereWorks-Signature: sha256=<hex of HMAC-SHA256(secret, raw request body)>
Content-Type: application/json
{ "event": "comment.created", "eventId": "evt-1", "ticketId": 4711,
"text": "Please send the part file.", "author": { "name": "Support Agent" } }
{ "event": "status.changed", "eventId": "evt-2", "ticketId": 4711, "status": "closed" }
Your reseller slug is shown on your Support page. ticketId is the number we sent you. An eventId makes a repeated delivery harmless. The customer is notified exactly as if your staff had replied in the portal. A wrong signature answers 401 and changes nothing.
// Node.js: sign a webhook body
const crypto = require('crypto');
const sig = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
Minimal receiver (ASP.NET)
app.MapGet("/ping", () => Results.Ok(new { ok = true }));
app.MapPost("/tickets", (JsonElement t) => Results.Created("/tickets/T-1", new { id = "T-1" }));
app.MapPost("/tickets/{id}/comments", (string id, JsonElement c) => Results.Created("", new { id = "c-1" }));
app.MapPatch("/tickets/{id}", (string id, JsonElement s) => Results.Ok());
Test mode
Test connection calls /ping and then POST /tickets with "test": true and a request id of 0. Both must answer 2xx. The result and the last 20 calls (time, call, HTTP status, duration, error - never a body or a key) are on your Support page.
Switching it off
Choose another provider and save, or ask a SphereHarness website administrator to disable the connector; new requests then stay in your SphereHarness queue only. Related: Support requests, Reseller portal.