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

# Bulk assign plan

> Assign a plan to multiple customers in one request, with optional entitlement or credit items

<Note>
  Each customer is processed independently. If some customers fail (e.g., customer not found, already subscribed), the others will still be assigned. Check both `succeeded` and `failed` arrays in the response.
</Note>

<Note>
  Use `skip_invoice: true` when migrating customers who have already paid outside of Metrifox. The subscription and order will be created, but no invoice will be generated.
</Note>

<Note>
  `billing_interval` is optional for free plans. You can omit it and the subscription will be created without a billing cycle. For paid plans, `billing_interval` is required and must match one of the intervals configured on the plan.
</Note>

<Note>
  Use `currency_code` when your plan has localized pricing in multiple currencies and you want to pin the subscription to a specific currency (e.g. `"EUR"` for a European customer). If omitted, the plan's default product currency is used.
</Note>

<Note>
  Use `start_date` to backdate subscriptions when onboarding was delayed. Pass a date string in the past (e.g. `"2026-04-01"`) and the subscription will be created with that start date. Combine with `skip_invoice: true` to avoid charging for the gap period. Future dates are not allowed.
</Note>


## OpenAPI

````yaml POST /api/v1/subscriptions/bulk-assign-plan
openapi: 3.0.1
info:
  title: Metrifox API Documentation
  version: v1
  description: >-
    Welcome to Metrifox Platform's API documentation. This comprehensive API
    suite enables seamless integration with our platform, providing secure and
    efficient access to our services.
servers:
  - url: https://{defaultHost}
    variables:
      defaultHost:
        default: api.metrifox.com
security:
  - api_key: []
paths:
  /api/v1/subscriptions/bulk-assign-plan:
    post:
      tags:
        - Subscriptions
      summary: Bulk assign customers to a plan
      description: >
        Assigns multiple customers to a plan in a single request. This is useful
        for:


        - **Customer migration**: Moving customers from an external system into
        Metrifox

        - **Batch onboarding**: Assigning a group of customers to the same plan
        at once

        - **Sales-led provisioning**: Programmatically setting up subscriptions
        for enterprise deals


        Each customer is processed independently. If a customer fails (e.g., not
        found, already subscribed), other customers will still be processed. The
        response includes both `succeeded` and `failed` arrays so you can handle
        partial failures.


        Use `skip_invoice: true` when migrating customers who have already paid
        externally — the subscription is created without generating an invoice.
      operationId: bulkAssignPlan
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - customer_keys
                - plan_key
              properties:
                customer_keys:
                  type: array
                  items:
                    type: string
                  description: Array of customer keys to assign to the plan
                  example:
                    - cust_001
                    - cust_002
                    - cust_003
                plan_key:
                  type: string
                  description: The offering key of the plan to assign
                  example: pro-plan
                billing_interval:
                  type: string
                  description: >
                    The billing interval for the subscription. Must be an
                    interval available on the plan.

                    Required for paid plans. Can be omitted when assigning a
                    free plan.
                  example: monthly
                currency_code:
                  type: string
                  description: >
                    The ISO 4217 currency code to use when selecting the plan's
                    price option.

                    Use this when your plan has localized pricing in multiple
                    currencies and you want

                    to assign a specific currency to the customer. If omitted,
                    the plan's default

                    product currency is used.
                  example: EUR
                items:
                  type: array
                  description: >-
                    Optional entitlement or credit items to include with the
                    subscription. Each item must have either a `feature_key` or
                    `credit_key`, plus a `quantity`.
                  items:
                    type: object
                    required:
                      - quantity
                    properties:
                      feature_key:
                        type: string
                        description: >-
                          The feature key of the entitlement to add. Mutually
                          exclusive with `credit_key`.
                        example: api-calls
                      credit_key:
                        type: string
                        description: >-
                          The credit key of the credit to add. Mutually
                          exclusive with `feature_key`.
                        example: message-credits
                      quantity:
                        type: integer
                        description: The quantity for this item
                        example: 100
                skip_invoice:
                  type: boolean
                  default: false
                  description: >
                    When `true`, subscriptions are created without generating
                    invoices. Use this for customer migrations where payment has
                    already been collected externally.
                start_date:
                  type: string
                  format: date
                  description: >
                    A date string in the past to backdate the subscription start
                    (e.g. `"2026-04-01"`). Use this when onboarding was delayed
                    and you want the subscription to reflect the original
                    agreed-upon start date.

                    Must be in the past — future dates are rejected. If omitted,
                    the subscription starts immediately.
                  example: '2026-04-01'
      responses:
        '200':
          description: Bulk assignment completed (may include partial failures)
          content:
            application/json:
              schema:
                type: object
                properties:
                  statusCode:
                    type: integer
                    example: 200
                  message:
                    type: string
                    example: Bulk plan assignment completed
                  data:
                    type: object
                    properties:
                      succeeded:
                        type: array
                        items:
                          type: object
                          properties:
                            customer_key:
                              type: string
                      failed:
                        type: array
                        items:
                          type: object
                          properties:
                            customer_key:
                              type: string
                            error:
                              type: string
                  errors:
                    type: object
              examples:
                all_succeeded:
                  summary: All customers assigned successfully
                  value:
                    statusCode: 200
                    message: Bulk plan assignment completed
                    meta: {}
                    data:
                      succeeded:
                        - customer_key: cust_001
                        - customer_key: cust_002
                      failed: []
                    errors: {}
                partial_failure:
                  summary: Some customers failed
                  value:
                    statusCode: 200
                    message: Bulk plan assignment completed
                    meta: {}
                    data:
                      succeeded:
                        - customer_key: cust_001
                      failed:
                        - customer_key: cust_999
                          error: Customer not found
                    errors: {}
        '400':
          description: >-
            Bad request — billing interval not available on the plan, or billing
            interval is missing for a paid plan
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                statusCode: 400
                message: The specified billing interval is not available for this plan
                errors: {}
        '401':
          description: Unauthorized - Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Plan not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                statusCode: 404
                message: Plan not found
                errors: {}
      x-codeSamples:
        - lang: curl
          label: cURL
          source: >
            curl -X POST
            https://api.metrifox.com/api/v1/subscriptions/bulk-assign-plan \
              -H "x-api-key: your_api_key" \
              -H "Content-Type: application/json" \
              -d '{
                "customer_keys": ["cust_001", "cust_002", "cust_003"],
                "plan_key": "pro-plan",
                "billing_interval": "monthly",
                "currency_code": "EUR",
                "skip_invoice": true,
                "start_date": "2026-04-01"
              }'
        - lang: python
          label: Python SDK
          source: |
            from metrifox_sdk import MetrifoxClient

            client = MetrifoxClient(api_key="your_api_key")

            result = client.subscriptions.bulk_assign_plan(
                customer_keys=["cust_001", "cust_002", "cust_003"],
                plan_key="pro-plan",
                billing_interval="monthly",
                currency_code="EUR",
                skip_invoice=True,
                start_date="2026-04-01"
            )
        - lang: js
          label: JavaScript SDK
          source: |
            import { init } from "metrifox-js";

            const metrifoxClient = init({
              apiKey: process.env.METRIFOX_API_KEY
            });

            const result = await metrifoxClient.subscriptions.bulkAssignPlan({
              customer_keys: ["cust_001", "cust_002", "cust_003"],
              plan_key: "pro-plan",
              billing_interval: "monthly",
              currency_code: "EUR",
              skip_invoice: true,
              start_date: "2026-04-01T00:00:00Z"
            });
        - lang: ruby
          label: Ruby SDK
          source: |
            require 'metrifox-sdk'

            METRIFOX_SDK = MetrifoxSDK.init({ api_key: "your-api-key" })

            result = METRIFOX_SDK.subscriptions.bulk_assign_plan(
              customer_keys: ["cust_001", "cust_002", "cust_003"],
              plan_key: "pro-plan",
              billing_interval: "monthly",
              currency_code: "EUR",
              skip_invoice: true,
              start_date: "2026-04-01T00:00:00Z"
            )
components:
  schemas:
    ErrorResponse:
      type: object
      properties:
        message:
          type: string
          description: Error message
        errors:
          type: object
          additionalProperties: true
          description: Detailed error information
  securitySchemes:
    api_key:
      type: apiKey
      name: x-api-key
      in: header

````