Overview
Parameters
Responses
Errors
POST/api/v1/subscribers
Create a subscriber
Creates a new subscriber record in WISPGate with core identity, contact, billing, and service-association data. This endpoint should be treated as a business-critical entry point because downstream workflows often depend on the quality of the initial record.
Purpose
Create base identity
Establish the customer record before service binding, billing actions, or provisioning flows begin.
Used by
Sales / onboarding / migration
This endpoint is typically used by onboarding forms, imports, integrations, and internal admin tools.
Critical note
Bad input creates downstream pain
Duplicate, incomplete, or malformed subscriber data will poison billing, support, and provisioning later.
Auth model
- Bearer token passed via
Authorization header
- Environment-specific base URL
- Optional idempotency key for safe retries on create actions
- Tenant or workspace scoping if multi-tenant access is enabled
Authorization: Bearer <api_token>
Content-Type: application/json
Accept: application/json
X-Idempotency-Key: 4b71d8f2-sample-key
X-Tenant-ID: tenant_demo_001
POST /api/v1/subscribers
{
"external_id": "crm-23991",
"full_name": "Jane Doe",
"email": "jane@example.com",
"phone": "+15550001234",
"status": "prospect",
"billing_profile_id": "bp_001",
"address": {
"line1": "101 Fiber Street",
"city": "Austin",
"state": "TX",
"postal_code": "78701"
},
"metadata": {
"source": "website_signup",
"campaign": "spring_launch"
}
}
Field behavior
external_id should be used when syncing from another system to prevent duplicate creation.
status should reflect lifecycle state, not arbitrary marketing labels.
billing_profile_id should reference a valid finance configuration if billing follows immediately.
metadata is useful, but do not dump unstructured garbage into it.
{
"success": true,
"data": {
"id": "sub_000184",
"external_id": "crm-23991",
"full_name": "Jane Doe",
"status": "prospect",
"billing_profile_id": "bp_001",
"created_at": "2026-04-13T10:21:00Z"
},
"meta": {
"request_id": "req_92aa7d",
"api_version": "v1"
}
}
Response design
- Use a predictable envelope for success and errors.
- Return identifiers that downstream systems can reference safely.
- Include request tracing metadata where possible for debugging and support.
- Do not hide useful details behind vague “ok” responses.
{ }
Request schema
| external_id | string / optional but strongly recommended for sync safety |
| full_name | string / required |
| email | string / optional |
| phone | string / optional |
| status | enum / required |
| billing_profile_id | string / optional |
| address | object / optional |
| metadata | object / optional |
[]
Response schema
| success | boolean |
| data.id | string / WISPGate subscriber ID |
| data.status | enum / current lifecycle state |
| data.created_at | timestamp / ISO 8601 |
| meta.request_id | string / traceable request reference |
| meta.api_version | string / version marker |
| 400 Bad Request | Malformed or missing required fields |
| 401 Unauthorized | Missing or invalid bearer token |
| 409 Conflict | Duplicate subscriber based on external_id or duplicate-rule policy |
| 422 Validation Error | Structured field validation failed |
| 429 Too Many Requests | Rate limit or abuse threshold triggered |
{
"success": false,
"error": {
"code": "duplicate_subscriber",
"message": "A subscriber with the provided external_id already exists.",
"field": "external_id"
},
"meta": {
"request_id": "req_19ba22",
"api_version": "v1"
}
}