> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vultlocal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Register Subscriber

> Create a new subscriber account with KYC details

<Info>
  For public registration without authentication, use the [Public Registration](#public-registration) endpoint instead.
</Info>

## Request

<ParamField header="Authorization" type="string" required>
  `Bearer olive_live_xxx` or `Bearer eyJ...` (JWT)
</ParamField>

<ParamField header="Content-Type" type="string" required>
  `application/json`
</ParamField>

### Body Parameters

<ParamField body="phone_number" type="string" required>
  Phone number in local format (`0771234567`) or E.164 (`+23279123456`)
</ParamField>

<ParamField body="first_name" type="string" required>
  Subscriber's first name
</ParamField>

<ParamField body="last_name" type="string" required>
  Subscriber's last name
</ParamField>

<ParamField body="pin" type="string" required>
  4-digit PIN for transactions (e.g., `1234`)
</ParamField>

<ParamField body="email" type="string">
  Email address
</ParamField>

<ParamField body="date_of_birth" type="string">
  Date of birth (`YYYY-MM-DD` format)
</ParamField>

<ParamField body="address" type="string">
  Physical address
</ParamField>

<ParamField body="id_number" type="string">
  National ID number
</ParamField>

<ParamField body="id_type" type="string">
  ID document type: `NATIONAL_ID`, `PASSPORT`, `DRIVERS_LICENSE`
</ParamField>

<ParamField body="id_document_url" type="string">
  URL to uploaded ID document image
</ParamField>

<ParamField body="selfie_url" type="string">
  URL to uploaded selfie for KYC verification
</ParamField>

<ParamField body="max_child_cards" type="integer" default="4">
  Maximum child cards allowed
</ParamField>

***

## Response

<ResponseField name="success" type="boolean">
  Whether registration succeeded
</ResponseField>

<ResponseField name="subscriber_id" type="string">
  Unique subscriber UUID (e.g., `sub_abc123`)
</ResponseField>

<ResponseField name="message" type="string">
  Human-readable result message
</ResponseField>

<ResponseField name="subscriber" type="object">
  Full subscriber object with all fields
</ResponseField>

***

## Examples

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://demo.api.vultlocal.com/api/v1/subscribers" \
    -H "Authorization: Bearer olive_live_xxx" \
    -H "Content-Type: application/json" \
    -d '{
      "phone_number": "0771234567",
      "first_name": "John",
      "last_name": "Doe",
      "pin": "1234",
      "email": "john@example.com",
      "date_of_birth": "1990-05-15"
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 201 Created theme={null}
  {
    "success": true,
    "subscriber_id": "sub_abc123",
    "message": "Subscriber registered successfully",
    "subscriber": {
      "id": "sub_abc123",
      "phone_number": "+23279123456",
      "first_name": "John",
      "last_name": "Doe",
      "email": "john@example.com",
      "kyc_level": 1,
      "status": "ACTIVE",
      "balance": "0.00 SLE",
      "created_at": "2025-01-15T10:30:00Z"
    }
  }
  ```

  ```json 409 Conflict theme={null}
  {
    "error": "Phone number already registered",
    "code": "DUPLICATE_PHONE"
  }
  ```
</ResponseExample>

***

## KYC Levels

Upon registration, subscribers start at KYC Level 1 with basic limits:

| Level | Max Balance    | Daily Limit   | Required        |
| ----- | -------------- | ------------- | --------------- |
| 1     | 500,000 SLE    | 100,000 SLE   | Phone + PIN     |
| 2     | 2,000,000 SLE  | 500,000 SLE   | + ID Document   |
| 3     | 10,000,000 SLE | 2,000,000 SLE | + Address Proof |

***

## Public Registration

<Info>
  For third-party integrations that don't have API keys, use the public endpoint.
</Info>

```http theme={null}
POST /api/v1/public/subscribers
```

Same request body, no Authorization header required. Rate limited per IP.

<RequestExample>
  ```bash Public Registration theme={null}
  curl -X POST "https://demo.api.vultlocal.com/api/v1/public/subscribers" \
    -H "Content-Type: application/json" \
    -d '{
      "phone_number": "0771234567",
      "first_name": "John",
      "last_name": "Doe",
      "pin": "1234"
    }'
  ```
</RequestExample>

***

## Errors

| Status | Code              | Description                               |
| ------ | ----------------- | ----------------------------------------- |
| 400    | `INVALID_REQUEST` | Missing required fields or invalid format |
| 400    | `INVALID_PIN`     | PIN must be exactly 4 digits              |
| 401    | `UNAUTHORIZED`    | Invalid or missing API key                |
| 409    | `DUPLICATE_PHONE` | Phone number already registered           |
| 500    | `INTERNAL_ERROR`  | Server error                              |


## OpenAPI

````yaml olive-openapi.json POST /subscribers
openapi: 3.0.0
info:
  description: >-
    API Gateway for OLIVE NFC Card Payment System - Comprehensive payment, card
    management, agent operations, and admin authentication. All /api/v1 routes
    require authentication using either API Key or JWT token.
  title: OLIVE NFC Card Payment API
  termsOfService: http://swagger.io/terms/
  contact:
    name: API Support
    email: support@olive.sl
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
  version: 1.0.0
servers:
  - url: https://olive-gateway-a6ba.onrender.com/api/v1
security: []
paths:
  /subscribers:
    post:
      tags:
        - Subscribers
      summary: Register a new subscriber
      description: Register a new subscriber with KYC details
      requestBody:
        $ref: '#/components/requestBodies/handler.RegisterSubscriberRequest'
      responses:
        '201':
          description: Subscriber created successfully
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
      security:
        - ApiKeyAuth: []
        - BearerAuth: []
components:
  requestBodies:
    handler.RegisterSubscriberRequest:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/handler.RegisterSubscriberRequest'
      description: Subscriber registration details
      required: true
  schemas:
    handler.RegisterSubscriberRequest:
      type: object
      required:
        - first_name
        - last_name
        - phone_number
        - pin
      properties:
        address:
          type: string
          example: 123 Main St
        category:
          type: string
          example: retail
        certificate_url:
          type: string
          example: https://example.com/cert.pdf
        district:
          type: string
          example: Western Urban
        email:
          type: string
          example: john@example.com
        first_name:
          type: string
          example: John
        id_back_url:
          type: string
          example: https://example.com/id_back.jpg
        id_front_url:
          type: string
          example: https://example.com/id_front.jpg
        kyc_level:
          type: integer
          example: 1
        last_name:
          type: string
          example: Doe
        max_child_cards:
          type: integer
          example: 4
        national_id:
          type: string
          example: NID123456
        organisation_name:
          type: string
          example: ABC Company Ltd
        organisation_type:
          type: string
          example: Limited Company
        other_names:
          type: string
          example: Michael
        phone_number:
          type: string
          example: '0771234567'
        pin:
          type: string
          example: '1234'
        referral_code:
          type: string
          example: REF123
        registration_id_no:
          type: string
          example: RC123456
        relationship_manager_id:
          type: integer
          example: 1
        whatsapp_number:
          type: string
          example: '0771234567'
  securitySchemes:
    ApiKeyAuth:
      description: >-
        API Key for third-party integrations (WhatsApp, Smart PAY, VULT).
        Format: 'Bearer olive_live_xxxxxxxxxxxxx'
      type: apiKey
      name: Authorization
      in: header
    BearerAuth:
      description: >-
        JWT token from admin login for administrative operations. Format:
        'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
      type: apiKey
      name: Authorization
      in: header

````