Skip to content

List my own API calls

GET
/reseller/v1/activity
curl --request GET \
--url 'https://api.nsin.cloud/reseller/v1/activity?method=GET' \
--header 'Authorization: Bearer <token>'

Every request you have made to this API, newest first, with the status and error it was answered with.

This is your integration’s log, not your clients’ traffic — for the requests the edge served for their domains, see /logs. The two are unrelated, and this is the one to read when the API itself is not behaving.

Failed authentication is recorded too, whenever the credential named a key_id that exists. That is deliberate and is the main reason this endpoint exists: a rejected token is the most common thing to get stuck on, and it is invisible everywhere else.

Each row carries the request_id that was returned in the X-Request-Id response header of the call it describes. Quote it in a support ticket and it identifies the exact request.

Rows are kept for RESELLER_ACTIVITY_RETENTION_DAYS (30 by default).

page
integer
>= 1
per_page
integer
>= 1 <= 100
failed_only
boolean

Only calls answered 4xx or 5xx. The usual starting point.

status
integer

Exact HTTP status, e.g. 401.

method
string
Allowed values: GET POST PUT PATCH DELETE
token_id
integer

Only calls made with one credential — which of your integrations is misbehaving.

request_id
string

The exact call, by the id from its X-Request-Id header.

since_hours
integer
>= 1 <= 8760

Only calls from the last N hours.

Your API calls, newest first.

Media type application/json
object
data
required
Array<object>

One request you made to this API, and the answer it got.

object
id
required
integer
created_at
required
string format: date-time
request_id
required

The X-Request-Id returned with this call. Quote it in a ticket.

string
token_id

The credential used. Absent when the call came from a dashboard session.

integer
token_name
string
method
required
string
path
required

What you asked for, query string included.

string
route

The route template it matched. Empty means it matched nothing — which is the answer when a 404 is really a wrong path.

string
status
required
integer
duration_ms
required

Server-side handling time. Excludes network and TLS, so a client-side timeout far larger than this one means the time went to the wire, not to us.

integer
error

The error field of the response. Present only for failures.

string
ip
required
string
user_agent
string
meta
required
object
page
required
integer
per_page
required
integer
total
required
integer
Example
{
"data": [
{
"request_id": "9f2b41e8a7c04f16",
"token_name": "WHMCS production",
"method": "POST",
"path": "/reseller/v1/clients?page=2",
"route": "/reseller/v1/clients/:clientId",
"status": 401,
"error": "Not Authorized"
}
]
}

Missing, malformed, expired, or revoked credential.

Media type application/json

Every error body carries error, a human-readable sentence. Some also carry code, a stable machine-readable reason — branch on that, never on the sentence, which is prose and gets reworded.

object
error
required
string
code

Present only on the failures worth branching on, and deliberately not an exhaustive enum: treat a code you do not recognise as if it were absent and fall back to the status code.

The ones that exist today:

  • credit_limit_reached — 402 from POST /services and POST /services/{serviceId}/change-plan. Your wallet, not the client’s: funding the purchase would take you past your overdraft (default 0, i.e. past zero). Top up; do not credit the client.
  • domain_disabled — 409 from a configuration write on a disabled domain (records, rules, cache, SSL, members, settings). The domain is read-only until POST /domains/{domainId}/enable.
  • unknown_rule_type — 404 from the rules paths when ruleType is not one of the documented values. You get this rather than an empty array, so a typo cannot read as a rule set that happens to be empty.
  • rate_limited — 429 from any route. Keyed per credential, so one runaway integration cannot lock its owner out of the dashboard.
  • session_check_failed — 503, and only on calls made with a dashboard session JWT. The session could not be verified, which is not the same as knowing it is revoked, so it is retryable and the session survives. Machine tokens never see this.
string
Example
{
"error": "forbidden",
"code": "credit_limit_reached"
}

Authenticated, but the target does not belong to you — or you are not a reseller at all.

This is the response the tenant-isolation matrix asserts on. Every route in this document is called with reseller B’s credential against reseller A’s ids, and must answer 403 or 404 with none of A’s data in the body.

Media type application/json

Every error body carries error, a human-readable sentence. Some also carry code, a stable machine-readable reason — branch on that, never on the sentence, which is prose and gets reworded.

object
error
required
string
code

Present only on the failures worth branching on, and deliberately not an exhaustive enum: treat a code you do not recognise as if it were absent and fall back to the status code.

The ones that exist today:

  • credit_limit_reached — 402 from POST /services and POST /services/{serviceId}/change-plan. Your wallet, not the client’s: funding the purchase would take you past your overdraft (default 0, i.e. past zero). Top up; do not credit the client.
  • domain_disabled — 409 from a configuration write on a disabled domain (records, rules, cache, SSL, members, settings). The domain is read-only until POST /domains/{domainId}/enable.
  • unknown_rule_type — 404 from the rules paths when ruleType is not one of the documented values. You get this rather than an empty array, so a typo cannot read as a rule set that happens to be empty.
  • rate_limited — 429 from any route. Keyed per credential, so one runaway integration cannot lock its owner out of the dashboard.
  • session_check_failed — 503, and only on calls made with a dashboard session JWT. The session could not be verified, which is not the same as knowing it is revoked, so it is retryable and the session survives. Machine tokens never see this.
string
Example
{
"error": "forbidden",
"code": "credit_limit_reached"
}

Something failed on our side. The body carries a human sentence and never an internal detail — a live sweep of this API once returned dial tcp 127.0.0.1:9000: connect: connection refused, which is our topology rather than an error message. That is now impossible.

Distinguish it from 503. A 503 means a dependency is down and the identical request will succeed later, so retry it. A 500 means the request hit a genuine fault: retrying it unchanged will fail the same way, and it should be reported with the X-Request-Id from the response header.

Declared on every operation because every operation can reach it. It was previously declared on exactly one, which left a generated client with no branch for the answer it is most likely to be surprised by.

Media type application/json

Every error body carries error, a human-readable sentence. Some also carry code, a stable machine-readable reason — branch on that, never on the sentence, which is prose and gets reworded.

object
error
required
string
code

Present only on the failures worth branching on, and deliberately not an exhaustive enum: treat a code you do not recognise as if it were absent and fall back to the status code.

The ones that exist today:

  • credit_limit_reached — 402 from POST /services and POST /services/{serviceId}/change-plan. Your wallet, not the client’s: funding the purchase would take you past your overdraft (default 0, i.e. past zero). Top up; do not credit the client.
  • domain_disabled — 409 from a configuration write on a disabled domain (records, rules, cache, SSL, members, settings). The domain is read-only until POST /domains/{domainId}/enable.
  • unknown_rule_type — 404 from the rules paths when ruleType is not one of the documented values. You get this rather than an empty array, so a typo cannot read as a rule set that happens to be empty.
  • rate_limited — 429 from any route. Keyed per credential, so one runaway integration cannot lock its owner out of the dashboard.
  • session_check_failed — 503, and only on calls made with a dashboard session JWT. The session could not be verified, which is not the same as knowing it is revoked, so it is retryable and the session survives. Machine tokens never see this.
string
Example
{
"error": "forbidden",
"code": "credit_limit_reached"
}