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

# Reset the test-mode sandbox

> Deletes every record created by test-mode (`f9_test_`) keys for your
workspace — leads, deals, customers, accounts and custom-object records,
plus their children. Live data is never touched. Only a test-mode key may
call this; a live key receives 403.




## OpenAPI

````yaml /api-reference/openapi.yaml post /v1/test-mode/reset
openapi: 3.1.0
info:
  title: Wander CRM Public API
  version: 1.0.0
  description: >
    The Wander CRM Public API enables third-party systems to integrate with

    Flow9 Engage CRM. Create leads, manage activities, retrieve customer

    profiles, and onboard new companies programmatically.


    ## Authentication

    Two credential types are accepted (see `securitySchemes`):

    - an **API key** in the `x-api-key` header — `f9_live_<32 hex>` for live
      traffic, `f9_test_<32 hex>` for the test sandbox (legacy `wcrm_live_` /
      `wcrm_test_` keys still authenticate but are no longer issued). Keys are
      created in **Settings > API Keys** or via `POST /v1/api-keys`.
    - an **OAuth 2.1 access token** in `Authorization: Bearer <jwt>` — what MCP
      clients and OAuth integrations send. Same scopes, same tenant isolation.

    If both are present, `x-api-key` wins. A request with neither is `401` with
    a

    `WWW-Authenticate: Bearer` header.


    These endpoints are **public** (no credential) — they are mounted before the

    auth middleware and apply their own per-IP rate limiting:

    - `GET /v1/health`

    - `POST /v1/onboarding` (tenant signup)

    - `GET /v1/availability` (module availability by country)


    `/v1/api-keys` is the one exception to the two credential types above: it is

    authenticated by a Company_Admin **session token** (Bearer), because a

    freshly-onboarded tenant has no API key yet.


    ## Rate limiting and quotas

    Three independent controls apply; a request must pass all of them.


    - **Per key** — sliding windows **per minute** (default 60, counted per
      endpoint) and **per hour** (default 1000, across the key). The
      `rate_limit_per_day` value stored on a key is **not enforced** in v1; it is
      kept for forward compatibility only.
    - **Per tenant** — one ceiling across every key the company holds (default
      600/minute, plus an optional daily cap derived from the plan). This is a
      protective backstop, not a meter.
    - **Monthly quota** — calls counted against the plan's `api_call_cap` for
    the
      billing period. Exhausted: `429 QUOTA_EXCEEDED`; no subscription: `402`;
      quota engine unreachable: `503 QUOTA_UNAVAILABLE` (fails closed).

    Every response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and

    `X-RateLimit-Reset`, describing whichever of the per-key / per-tenant
    windows

    is closest to rejecting. A `429` adds `Retry-After`. A monthly-quota refusal

    adds `X-Quota-Limit`, `X-Quota-Used` and `X-Quota-Remaining`. Full detail:

    `docs/api/rate-limits.md`.


    ## Response Envelope

    All responses use a consistent JSON envelope:

    ```json

    {
      "success": true | false,
      "data": { ... },          // present on success
      "error": { "code": "...", "message": "...", "details": ... }, // present on error
      "meta": { "request_id": "uuid", "timestamp": "ISO 8601" }
    }

    ```
  contact:
    name: Flow9 API Support
    email: api-support@flow9.online
  license:
    name: Proprietary
    url: https://flow9.online
servers:
  - url: https://mwxpyoqrtdfxubdotbmj.supabase.co/functions/v1/public-api
    description: Production API
security:
  - ApiKeyAuth: []
  - BearerAuth: []
tags:
  - name: Health
    description: Service health check
  - name: Onboarding
    description: Company and admin user onboarding
  - name: Packages
    description: The sellable package catalogue (plans and add-on modules)
  - name: API Keys
    description: >-
      Headless API-key bootstrap — mint, list and revoke keys with a session
      token
  - name: Billing
    description: >-
      Read the tenant's plan, seats, trial, entitled modules, API quota and
      prepaid balance
  - name: Users
    description: >-
      The people in the workspace — list for assignment, create, deactivate,
      change role
  - name: Access control
    description: >-
      Read-only view of the authz engine: roles, permission profiles, the module
      × action matrix and role data-scope rules
  - name: Org structure
    description: >-
      The org tree (regions, countries, branches, teams), branches, and which
      users sit on which node
  - name: Settings
    description: >-
      Pipeline configuration: lead statuses and deal stages, tags, sources,
      duplicate-check fields, SLA policies
  - name: Scheduling
    description: >-
      When people are free and booking them: availability, slots, offer tokens,
      holds, assignments, bookings
  - name: Search & reports
    description: Cross-object search, aggregation, pipeline breakdown and saved reports
  - name: Attachments
    description: 'Files on records: upload, list, short-lived download links, delete'
  - name: Campaigns
    description: >-
      Read campaigns, their channels, runs and delivery stats; a record's
      message timeline
  - name: Messages
    description: 'Draft-and-approve messaging: prepare a message for a person to send'
  - name: Suppression
    description: Sending numbers, the do-not-call list and the email suppression list
  - name: Customers
    description: Customer profile retrieval
  - name: Leads
    description: Lead creation and management
  - name: Activities
    description: Deal and lead activity tracking
  - name: Objects
    description: >-
      Discover the objects and fields a key can see, and manage tenant-defined
      fields
  - name: Records
    description: >-
      Generic record CRUD, batch writes and per-record notes, tasks and
      activities
  - name: Webhooks
    description: Webhook subscriptions, deliveries, replays and the event catalogue
  - name: Test mode
    description: Sandbox controls available to `f9_test_` keys only
paths:
  /v1/test-mode/reset:
    post:
      tags:
        - Test mode
      summary: Reset the test-mode sandbox
      description: >
        Deletes every record created by test-mode (`f9_test_`) keys for your

        workspace — leads, deals, customers, accounts and custom-object records,

        plus their children. Live data is never touched. Only a test-mode key
        may

        call this; a live key receives 403.
      operationId: resetTestMode
      responses:
        '200':
          description: Sandbox reset; row counts deleted per object.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      reset:
                        type: boolean
                      deleted:
                        type: object
                  meta:
                    $ref: '#/components/schemas/Meta'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
components:
  schemas:
    Meta:
      type: object
      properties:
        request_id:
          type: string
          format: uuid
        timestamp:
          type: string
          format: date-time
        rate_limit:
          type: object
          properties:
            limit:
              type: integer
            remaining:
              type: integer
            reset:
              type: integer
    ErrorBody:
      type: object
      required:
        - success
        - error
        - meta
      properties:
        success:
          type: boolean
          enum:
            - false
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              $ref: '#/components/schemas/ErrorCode'
            message:
              type: string
              description: >
                Human-readable message. Never contains internal detail, stack
                traces

                or upstream provider text.
            details:
              description: Additional context (field errors, available values, etc.)
        meta:
          $ref: '#/components/schemas/Meta'
    ErrorCode:
      type: string
      description: >
        Machine-readable error code. Branch on this, not on `message` — messages
        are

        human-readable and may change without notice.
      enum:
        - MISSING_API_KEY
        - AUTH_INVALID_KEY
        - API_KEY_EXPIRED
        - API_KEY_REVOKED
        - FORBIDDEN_SCOPE
        - IP_NOT_ALLOWED
        - MODULE_DISABLED
        - RATE_LIMIT_EXCEEDED
        - QUOTA_EXCEEDED
        - QUOTA_UNAVAILABLE
        - VALIDATION_ERROR
        - MISSING_REQUIRED_FIELD
        - INVALID_FIELD_FORMAT
        - NOT_FOUND
        - ALREADY_EXISTS
        - CONFLICT
        - SEAT_LIMIT_REACHED
        - NO_BILLING_CUSTOMER
        - AGREEMENT_ACTIVE
        - CARD_CHARGE_FAILED
        - NO_ACTIVE_SUBSCRIPTION
        - IDEMPOTENCY_KEY_REQUIRED
        - IDEMPOTENCY_CONFLICT
        - IDEMPOTENCY_IN_PROGRESS
        - INTERNAL_ERROR
        - SERVICE_UNAVAILABLE
        - METHOD_NOT_ALLOWED
  responses:
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorBody'
          example:
            success: false
            error:
              code: AUTH_INVALID_KEY
              message: Invalid API key
            meta:
              request_id: 550e8400-e29b-41d4-a716-446655440000
              timestamp: '2026-02-15T10:00:00.000Z'
    Forbidden:
      description: Insufficient scope, expired/revoked key, or IP not allowed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorBody'
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >
        API key from Settings > API Keys or `POST /v1/api-keys`. Format

        `f9_live_<32 hex chars>` (live) or `f9_test_<32 hex chars>` (sandbox —
        no

        real sends, ever). Legacy `wcrm_live_` / `wcrm_test_` keys still

        authenticate but are no longer issued. Shown once at creation; only a
        hash

        is stored.
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >
        OAuth 2.1 access token (`Authorization: Bearer <jwt>`), issued by the

        Flow9 authorization server to MCP clients and OAuth integrations.
        Carries

        the same `module:action` scopes as an API key and is subject to the same

        rate limits and tenant isolation. On `/v1/api-keys` ONLY, this header

        carries a Company_Admin **session token** instead.

````