Documentation menu

Docs

Provisioning

Create, suspend, resume and terminate monitored services for your customers.

Create, suspend, resume and terminate monitored services for your customers. These are the endpoints the WHMCS module calls from its provisioning hooks. Call them directly if you integrate with a different billing system. All provisioning actions are idempotent: repeating a call for a service that is already in the target state succeeds with a note in the response.

Every endpoint in this group is also available under the /api/v1/provisioning/* prefix (for example /api/v1/provisioning/provision). The two namespaces are identical. Pick one and stay consistent.

Endpoint actions (suspend, resume, terminate) address a monitored server by endpoint_id; subscription and domain actions address the WHMCS service by client_id + service_id (+ product_slug).

Provision endpoint monitoring

POST/api/v1/whmcs/provision
Auth: Bearer API keyRate limit: 60 requests / minute per API key

Start monitoring a server for a customer. Creates the monitored endpoint (and the customer's account on first use) and schedules the first scan. Idempotent: provisioning the same IP again for the same customer returns the existing endpoint with a note.

  • When the IP is already monitored for this customer, the call returns 200 with the existing endpoint_id and a note field instead of creating a duplicate.

Body parameters

NameTypeRequiredNotes
client_idintegerRequiredWHMCS client ID of the customer.min:1
ip_addressipRequiredIPv4 or IPv6 address of the server to monitor.
service_idintegerOptionalWHMCS service ID linking this endpoint to a product instance.min:1
hostnamestringOptionalDisplay hostname shown alongside the IP.max:255
client_namestringOptionalCustomer name, used to create their account on first provision.max:255
client_emailemailOptionalCustomer email, used to create their account on first provision.max:255
product_slugstringOptionalPlatform product to bill this endpoint against.max:50
plan_slugstringOptionalPlan tier for the product.max:50
mrrnumericOptionalMonthly recurring revenue you charge for this service, for revenue reporting.min:0.01 · max:9999.99
Example request
curl -X POST 'https://portal.example.com/api/v1/whmcs/provision' \
  -H 'Authorization: Bearer $AEGIS_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "client_id": 1042,
  "ip_address": "203.0.113.10",
  "service_id": 2251,
  "hostname": "web01.example.com",
  "client_name": "Jane Doe",
  "client_email": "jane@example.com",
  "product_slug": "port_monitoring",
  "plan_slug": "starter",
  "mrr": 19
}'
Response: 201
{
  "success": true,
  "data": {
    "endpoint_id": "9f2c1e4a-5b6d-4e7f-8a9b-0c1d2e3f4a5b",
    "status": "active"
  },
  "meta": {
    "version": "v1",
    "timestamp": "2026-07-12T09:30:00+00:00"
  }
}

Errors

CodeStatusMeaning
ENDPOINT_LIMIT_EXCEEDED403The customer's plan does not allow another endpoint. Upgrade the plan or terminate an endpoint first.
TENANT_NOT_FOUND401The API key did not resolve to an account.

Suspend endpoint monitoring

POST/api/v1/whmcs/suspend
Auth: Bearer API keyRate limit: 60 requests / minute per API key

Pause monitoring for an endpoint (for example on an unpaid invoice). Scans stop; the endpoint and its history are kept.

Body parameters

NameTypeRequiredNotes
endpoint_idstringRequiredThe endpoint UUID returned by the provision call.uuid
Example request
curl -X POST 'https://portal.example.com/api/v1/whmcs/suspend' \
  -H 'Authorization: Bearer $AEGIS_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "endpoint_id": "9f2c1e4a-5b6d-4e7f-8a9b-0c1d2e3f4a5b"
}'
Response: 200
{
  "success": true,
  "data": {
    "endpoint_id": "9f2c1e4a-5b6d-4e7f-8a9b-0c1d2e3f4a5b",
    "status": "paused"
  },
  "meta": {
    "version": "v1",
    "timestamp": "2026-07-12T09:30:00+00:00"
  }
}

Errors

CodeStatusMeaning
ENDPOINT_NOT_FOUND404No endpoint with that ID belongs to your account.

Resume endpoint monitoring

POST/api/v1/whmcs/resume
Auth: Bearer API keyRate limit: 60 requests / minute per API key

Resume monitoring for a suspended endpoint. Scanning picks up on the normal schedule.

Body parameters

NameTypeRequiredNotes
endpoint_idstringRequiredThe endpoint UUID returned by the provision call.uuid
Example request
curl -X POST 'https://portal.example.com/api/v1/whmcs/resume' \
  -H 'Authorization: Bearer $AEGIS_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "endpoint_id": "9f2c1e4a-5b6d-4e7f-8a9b-0c1d2e3f4a5b"
}'
Response: 200
{
  "success": true,
  "data": {
    "endpoint_id": "9f2c1e4a-5b6d-4e7f-8a9b-0c1d2e3f4a5b",
    "status": "active"
  },
  "meta": {
    "version": "v1",
    "timestamp": "2026-07-12T09:30:00+00:00"
  }
}

Errors

CodeStatusMeaning
ENDPOINT_NOT_FOUND404No endpoint with that ID belongs to your account.

Terminate endpoint monitoring

POST/api/v1/whmcs/terminate
Auth: Bearer API keyRate limit: 60 requests / minute per API key

Stop monitoring an endpoint permanently (soft delete). Use when the customer's service is cancelled.

Body parameters

NameTypeRequiredNotes
endpoint_idstringRequiredThe endpoint UUID returned by the provision call.uuid
Example request
curl -X POST 'https://portal.example.com/api/v1/whmcs/terminate' \
  -H 'Authorization: Bearer $AEGIS_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "endpoint_id": "9f2c1e4a-5b6d-4e7f-8a9b-0c1d2e3f4a5b"
}'
Response: 200
{
  "success": true,
  "data": {
    "endpoint_id": "9f2c1e4a-5b6d-4e7f-8a9b-0c1d2e3f4a5b",
    "status": "terminated"
  },
  "meta": {
    "version": "v1",
    "timestamp": "2026-07-12T09:30:00+00:00"
  }
}

Errors

CodeStatusMeaning
ENDPOINT_NOT_FOUND404No endpoint with that ID belongs to your account.

Trigger a manual scan

POST/api/v1/whmcs/scan-endpoint
Auth: Bearer API keyRate limit: 60 requests / minute per API key

Queue an on-demand scan for one of the customer's endpoints. Scans are asynchronous. The response confirms the scan was queued, and results appear on the endpoint once it completes. Manual scans are rate limited per endpoint with a cooldown window.

Body parameters

NameTypeRequiredNotes
client_idintegerRequiredWHMCS client ID of the customer who owns the endpoint.min:1
endpoint_iduuidRequiredUUID of the endpoint to scan.
Example request
curl -X POST 'https://portal.example.com/api/v1/whmcs/scan-endpoint' \
  -H 'Authorization: Bearer $AEGIS_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "client_id": 1042,
  "endpoint_id": "9f2c1e4a-5b6d-4e7f-8a9b-0c1d2e3f4a5b"
}'
Response: 202
{
  "success": true,
  "data": {
    "scan_id": "3c8d0f6b-2a1e-4c5d-9e8f-7a6b5c4d3e2f",
    "status": "pending",
    "cooldown_seconds": 3600
  },
  "meta": {
    "version": "v1",
    "timestamp": "2026-07-12T09:30:00+00:00"
  }
}

Errors

CodeStatusMeaning
ENDPOINT_NOT_FOUND404No endpoint with that ID belongs to the customer.
ENDPOINT_NOT_ACTIVE409The endpoint is paused or terminated. Resume it before scanning.
RATE_LIMITED429The endpoint is still in its scan cooldown. details.retry_after_seconds says when to retry.
SCANNING_UNAVAILABLE503The scanning service is temporarily unavailable.
SCAN_DISPATCH_FAILED500The scan could not be queued. Try again.

Provision domain monitoring

POST/api/v1/whmcs/provision-domain
Auth: Bearer API keyRate limit: 60 requests / minute per API key

Start watching a domain for leaked credentials and dark-web mentions. The domain is normalized (URLs are reduced to their hostname) before validation. Idempotent: an already-monitored domain returns its existing record with a note, and a previously terminated domain is restored.

Body parameters

NameTypeRequiredNotes
client_idintegerRequiredWHMCS client ID of the customer.min:1
domainstringRequiredDomain to monitor. Full URLs are accepted and reduced to the hostname.max:253 · valid domain
service_idintegerRequiredWHMCS service ID linking this domain to a product instance.min:1
client_namestringOptionalCustomer name, used to create their account on first provision.max:255
client_emailemailOptionalCustomer email, used to create their account on first provision.max:255
Example request
curl -X POST 'https://portal.example.com/api/v1/whmcs/provision-domain' \
  -H 'Authorization: Bearer $AEGIS_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "client_id": 1042,
  "domain": "example.com",
  "service_id": 2251,
  "client_name": "Jane Doe",
  "client_email": "jane@example.com"
}'
Response: 201
{
  "success": true,
  "data": {
    "monitored_domain_id": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b",
    "domain": "example.com",
    "status": "active"
  },
  "meta": {
    "version": "v1",
    "timestamp": "2026-07-12T09:30:00+00:00"
  }
}

Errors

CodeStatusMeaning
DOMAIN_LIMIT_EXCEEDED403The customer has used all their domain slots. Increase the subscription quantity first.

Suspend domain monitoring

POST/api/v1/whmcs/suspend-domain
Auth: Bearer API keyRate limit: 60 requests / minute per API key

Pause monitoring for a domain. Leak scanning stops; findings and history are kept.

Body parameters

NameTypeRequiredNotes
monitored_domain_iduuidRequiredUUID returned by the provision-domain call.
Example request
curl -X POST 'https://portal.example.com/api/v1/whmcs/suspend-domain' \
  -H 'Authorization: Bearer $AEGIS_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "monitored_domain_id": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b"
}'
Response: 200
{
  "success": true,
  "data": {
    "monitored_domain_id": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b",
    "status": "paused"
  },
  "meta": {
    "version": "v1",
    "timestamp": "2026-07-12T09:30:00+00:00"
  }
}

Errors

CodeStatusMeaning
DOMAIN_NOT_FOUND404No monitored domain with that ID belongs to your account.

Resume domain monitoring

POST/api/v1/whmcs/resume-domain
Auth: Bearer API keyRate limit: 60 requests / minute per API key

Resume monitoring for a suspended domain.

Body parameters

NameTypeRequiredNotes
monitored_domain_iduuidRequiredUUID returned by the provision-domain call.
Example request
curl -X POST 'https://portal.example.com/api/v1/whmcs/resume-domain' \
  -H 'Authorization: Bearer $AEGIS_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "monitored_domain_id": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b"
}'
Response: 200
{
  "success": true,
  "data": {
    "monitored_domain_id": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b",
    "status": "active"
  },
  "meta": {
    "version": "v1",
    "timestamp": "2026-07-12T09:30:00+00:00"
  }
}

Errors

CodeStatusMeaning
DOMAIN_NOT_FOUND404No monitored domain with that ID belongs to your account.

Terminate domain monitoring

POST/api/v1/whmcs/terminate-domain
Auth: Bearer API keyRate limit: 60 requests / minute per API key

Stop monitoring a domain permanently. Use when the customer's domain-monitoring service is cancelled.

Body parameters

NameTypeRequiredNotes
monitored_domain_iduuidRequiredUUID returned by the provision-domain call.
Example request
curl -X POST 'https://portal.example.com/api/v1/whmcs/terminate-domain' \
  -H 'Authorization: Bearer $AEGIS_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "monitored_domain_id": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b"
}'
Response: 200
{
  "success": true,
  "data": {
    "monitored_domain_id": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b",
    "status": "terminated"
  },
  "meta": {
    "version": "v1",
    "timestamp": "2026-07-12T09:30:00+00:00"
  }
}

Errors

CodeStatusMeaning
DOMAIN_NOT_FOUND404No monitored domain with that ID belongs to your account.

Change a monitored domain

POST/api/v1/whmcs/update-domain
Auth: Bearer API keyRate limit: 60 requests / minute per API key

Point an existing domain-monitoring service at a different domain (for example after a customer rebrand). Scan history for the old domain stays attached to the record; scanning continues against the new domain.

Body parameters

NameTypeRequiredNotes
monitored_domain_iduuidRequiredUUID returned by the provision-domain call.
domainstringRequiredThe new domain to monitor.max:253 · valid domain
Example request
curl -X POST 'https://portal.example.com/api/v1/whmcs/update-domain' \
  -H 'Authorization: Bearer $AEGIS_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "monitored_domain_id": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b",
  "domain": "example.net"
}'
Response: 200
{
  "success": true,
  "data": {
    "monitored_domain_id": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b",
    "domain": "example.net",
    "status": "active"
  },
  "meta": {
    "version": "v1",
    "timestamp": "2026-07-12T09:30:00+00:00"
  }
}

Errors

CodeStatusMeaning
DOMAIN_NOT_FOUND404No monitored domain with that ID belongs to your account.
DOMAIN_ALREADY_EXISTS409The customer already monitors the new domain.

Provision a subscription

POST/api/v1/whmcs/provision-subscription
Auth: Bearer API keyRate limit: 60 requests / minute per API key

Create (or update) a standalone product subscription for a customer, used for monitoring products that are not tied to a single server, such as domain-monitoring slots. Per-plan products take plan_slug; per-unit products take quantity.

  • Returns 201 when the subscription is created and 200 when an existing subscription is updated.

Body parameters

NameTypeRequiredNotes
client_idintegerRequiredWHMCS client ID of the customer.min:1
service_idintegerRequiredWHMCS service ID for this product instance.min:1
product_slugstringRequiredPlatform product to subscribe the customer to.max:50
plan_slugstringOptionalPlan tier (for per-plan products such as port_monitoring).max:50
quantityintegerOptionalUnit count (for per-unit products such as domain_monitoring slots).min:1 · max:10000
mrrnumericOptionalMonthly recurring revenue you charge, for revenue reporting.min:0.01 · max:9999.99
client_namestringOptionalCustomer name, used to create their account on first provision.max:255
client_emailemailOptionalCustomer email, used to create their account on first provision.max:255
Example request
curl -X POST 'https://portal.example.com/api/v1/whmcs/provision-subscription' \
  -H 'Authorization: Bearer $AEGIS_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "client_id": 1042,
  "service_id": 2260,
  "product_slug": "domain_monitoring",
  "plan_slug": "professional",
  "quantity": 5,
  "mrr": 25,
  "client_name": "Jane Doe",
  "client_email": "jane@example.com"
}'
Response: 201
{
  "success": true,
  "data": {
    "subscription_id": "7b6a5c4d-3e2f-4a1b-8c9d-0e1f2a3b4c5d",
    "product_slug": "domain_monitoring",
    "plan_slug": null,
    "quantity": 5,
    "status": "active"
  },
  "meta": {
    "version": "v1",
    "timestamp": "2026-07-12T09:30:00+00:00"
  }
}

Errors

CodeStatusMeaning
PRODUCT_NOT_FOUND404Unknown product_slug.

Suspend a subscription

POST/api/v1/whmcs/suspend-subscription
Auth: Bearer API keyRate limit: 60 requests / minute per API key

Pause a customer's product subscription. Endpoints and domains under the subscription are paused with it.

Body parameters

NameTypeRequiredNotes
client_idintegerRequiredWHMCS client ID of the customer.min:1
service_idintegerRequiredWHMCS service ID for this product instance.min:1
product_slugstringRequiredProduct of the subscription to suspend.max:50
Example request
curl -X POST 'https://portal.example.com/api/v1/whmcs/suspend-subscription' \
  -H 'Authorization: Bearer $AEGIS_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "client_id": 1042,
  "service_id": 2260,
  "product_slug": "domain_monitoring"
}'
Response: 200
{
  "success": true,
  "data": {
    "subscription_id": "7b6a5c4d-3e2f-4a1b-8c9d-0e1f2a3b4c5d",
    "status": "suspended"
  },
  "meta": {
    "version": "v1",
    "timestamp": "2026-07-12T09:30:00+00:00"
  }
}

Errors

CodeStatusMeaning
PRODUCT_NOT_FOUND404Unknown product_slug.
WHMCS_CLIENT_NOT_FOUND404The customer has no records for this service.
SUBSCRIPTION_NOT_FOUND404The customer has no subscription for this product and service.

Resume a subscription

POST/api/v1/whmcs/resume-subscription
Auth: Bearer API keyRate limit: 60 requests / minute per API key

Resume a suspended product subscription. Endpoints and domains under the subscription resume with it.

Body parameters

NameTypeRequiredNotes
client_idintegerRequiredWHMCS client ID of the customer.min:1
service_idintegerRequiredWHMCS service ID for this product instance.min:1
product_slugstringRequiredProduct of the subscription to resume.max:50
Example request
curl -X POST 'https://portal.example.com/api/v1/whmcs/resume-subscription' \
  -H 'Authorization: Bearer $AEGIS_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "client_id": 1042,
  "service_id": 2260,
  "product_slug": "domain_monitoring"
}'
Response: 200
{
  "success": true,
  "data": {
    "subscription_id": "7b6a5c4d-3e2f-4a1b-8c9d-0e1f2a3b4c5d",
    "status": "active"
  },
  "meta": {
    "version": "v1",
    "timestamp": "2026-07-12T09:30:00+00:00"
  }
}

Errors

CodeStatusMeaning
PRODUCT_NOT_FOUND404Unknown product_slug.
WHMCS_CLIENT_NOT_FOUND404The customer has no records for this service.
SUBSCRIPTION_NOT_FOUND404The customer has no subscription for this product and service.

Terminate a subscription

POST/api/v1/whmcs/terminate-subscription
Auth: Bearer API keyRate limit: 60 requests / minute per API key

End a customer's product subscription permanently. Endpoints and domains under the subscription are terminated with it.

Body parameters

NameTypeRequiredNotes
client_idintegerRequiredWHMCS client ID of the customer.min:1
service_idintegerRequiredWHMCS service ID for this product instance.min:1
product_slugstringRequiredProduct of the subscription to terminate.max:50
Example request
curl -X POST 'https://portal.example.com/api/v1/whmcs/terminate-subscription' \
  -H 'Authorization: Bearer $AEGIS_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "client_id": 1042,
  "service_id": 2260,
  "product_slug": "domain_monitoring"
}'
Response: 200
{
  "success": true,
  "data": {
    "subscription_id": "7b6a5c4d-3e2f-4a1b-8c9d-0e1f2a3b4c5d",
    "status": "terminated"
  },
  "meta": {
    "version": "v1",
    "timestamp": "2026-07-12T09:30:00+00:00"
  }
}

Errors

CodeStatusMeaning
PRODUCT_NOT_FOUND404Unknown product_slug.
WHMCS_CLIENT_NOT_FOUND404The customer has no records for this service.
SUBSCRIPTION_NOT_FOUND404The customer has no subscription for this product and service.

Change a subscription plan or quantity

POST/api/v1/whmcs/change-subscription
Auth: Bearer API keyRate limit: 60 requests / minute per API key

Upgrade or downgrade a subscription: change the plan tier of a per-plan product or the unit count of a per-unit product. Downgrades are checked against current usage first, so a customer using 8 domain slots cannot drop to 5.

  • A no-op change (already on the requested plan and quantity) returns changed: false with the current plan.
  • At least one of new_plan_slug or new_quantity is required.

Body parameters

NameTypeRequiredNotes
client_idintegerRequiredWHMCS client ID of the customer.min:1
service_idintegerRequiredWHMCS service ID for this product instance.min:1
product_slugstringRequiredProduct of the subscription to change.max:50
new_plan_slugstringOptionalTarget plan tier for per-plan products.max:50
new_quantityintegerOptionalTarget unit count for per-unit products.min:1 · max:10000
forcebooleanOptionalReserved for administrative overrides; leave unset in normal integrations.
Example request
curl -X POST 'https://portal.example.com/api/v1/whmcs/change-subscription' \
  -H 'Authorization: Bearer $AEGIS_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "client_id": 1042,
  "service_id": 2260,
  "product_slug": "port_monitoring",
  "new_plan_slug": "professional",
  "new_quantity": 10
}'
Response: 200
{
  "success": true,
  "data": {
    "changed": true,
    "subscription_id": "7b6a5c4d-3e2f-4a1b-8c9d-0e1f2a3b4c5d",
    "plan_slug": "professional",
    "direction": "upgrade",
    "previous_plan_slug": "starter",
    "effective_at": "2026-07-12T09:30:00+00:00"
  },
  "meta": {
    "version": "v1",
    "timestamp": "2026-07-12T09:30:00+00:00"
  }
}

Errors

CodeStatusMeaning
PRODUCT_NOT_FOUND404Unknown product_slug.
SUBSCRIPTION_NOT_FOUND404The customer has no subscription for this product and service.
DOWNGRADE_USAGE_EXCEEDED422Current usage exceeds the target plan or quantity. details carries current_usage and new_limit.
SUBSCRIPTION_NOT_CHANGEABLE422The subscription is in a state that cannot be changed (for example terminated).

Compiled from the AegisWhite platform (build 6bffe04, module v1.7.3, 2026-07-14).