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

# Bulk Usage Upload

> Report usage in bulk.

export const IntRedir = () => {
  if (typeof document === "undefined") {
    return null;
  } else {
    setTimeout(() => {
      const currentUrl = new URL(window.location.href);
      if (currentUrl.hostname === 'docs-int.wingback.com') {
        currentUrl.hostname = 'docs.wingback.com';
        window.location.replace(currentUrl.toString());
      }
    }, 1);
    return <></>;
  }
};

<IntRedir />

This endpoint allows you to upload a significant volume of usage events for multiple customers simultaneously.
For detailed instructions and best practices on implementation, please refer to the [Metering Guide](/dev/guides/metering).

The endpoint conducts preliminary validation immediately and a more in-depth validation later during the creation of billing events. If any issues are detected during the initial validation, they will be communicated in the response body, with the index corresponding to the erroneous entry. A 4xx error indicates an issue with the data you provided and should not be retried. Entries that pass validation do not return any feedback and can be deemed as successfully committed. In case of a failure (5xx) or connection issues, we recommend implementing an exponential back-off retry strategy.

## Rate limits

This endpoint is designed for periodic uploads of (pre-)aggregated usage data in larger batches. By default, we guarantee a throughput capacity of 100 requests and 150,000 usage events per minute, per customer. However, our infrastructure is capable of scaling significantly beyond these limits. If your application's demands approach or exceed these constraints, please get in touch with us.

<RequestExample>
  ```bash theme={null}
  curl --request POST \
    --url https://api.wingback.com/v1/c/usage \
    --header 'wb-key: <wb-key>' \
    --data '[
    {
      "customer_id": "Cust_c40bea18-c0c9-44b1-bd0c-43f5283e1670",
      "feature_slug": "FEATURE_A",
      "units": 10
    },
    {
      "customer_id": "Cust_c40bea18-c0c9-44b1-bd0c-43f5283e1670",
      "feature_slug": "FEATURE_B",
      "units": 1
    }
  ]'
  ```
</RequestExample>

<ResponseExample>
  ```json Response theme={null}
  [
    {
      "index": 0,
      "status": 400,
      "feedback": {
        "contract": {
          "type": "error",
          "value": "Contract not found"
        }
      }
    },
    {
      "index": 6,
      "status": 400,
      "feedback": {
        "activation": {
          "type": "error",
          "value": "timestamp provided is before contract activation date 2023-03-19T05:03:51.756Z"
        }
      }
    }
  ]
  ```
</ResponseExample>


## OpenAPI

````yaml POST /v1/c/usage/bulk
openapi: 3.0.3
info:
  title: wingback-api
  description: ''
  contact:
    name: ''
  license:
    name: commercial
  version: 0.1.0
servers:
  - url: http://127.0.0.1:8080
    description: Local server
  - url: https://api.app.test.wingback.com
    description: Testing server
security: []
paths:
  /v1/c/usage/bulk:
    post:
      tags:
        - usage
      summary: Record Bulk Usage Events
      operationId: bulk
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/inbound.usage.Usage'
            example:
              - customer_id: Cust_c40bea18-c0c9-44b1-bd0c-43f5283e1670
                feature_slug: FEATURE_A
                units: '10'
              - customer_id: Cust_c40bea18-c0c9-44b1-bd0c-43f5283e1670
                feature_slug: FEATURE_B
                units: '1'
        required: true
      responses:
        '200':
          description: Recorded
        '422':
          description: Malformed payload
      security:
        - api-key: []
        - wb_user_cookie: []
components:
  schemas:
    inbound.usage.Usage:
      type: object
      description: |-
        Structure to report Usage for Usage-based features in a Contract
        Currently the only reporting strategy supported is additive, meaning
        that all reported usage units are summed for the billing period.
        This requires additional care from the reporter to ensure
        that no double-reporting takes place
      required:
        - feature_slug
        - units
        - customer_id
      properties:
        customer_id:
          $ref: '#/components/schemas/Id'
        feature_slug:
          type: string
          description: Slug of the feature usage is reported for
        is_absolute:
          type: boolean
          description: >-
            Setting this to true would discard all events with timestamp
            preceding this event,

            and will use this event's `units` as zero value for usage in the
            current billing period
          nullable: true
        metadata:
          type: object
          description: |-
            Any metadata you wish to associate with the event
            Note that both keys and values can only be a string
            Additionally, please avoid escaping non-ascii symbols
          additionalProperties:
            type: string
        timestamp:
          type: string
          format: date-time
          description: |-
            Date for the Usage.
            When usage period is closed, all usage which timestamp falls between
            Usage period (Billing period) start and end will be summed.
          nullable: true
        units:
          type: string
          description: Amount of units consumed since the last report
    Id:
      type: string
      description: >-
        Unique identifier of an object. Consists of object class prefix and a
        UUID
      example: Cust_c40bea18-c0c9-44b1-bd0c-43f5283e1670
  securitySchemes:
    api-key:
      type: apiKey
      in: header
      name: wb-key
    wb_user_cookie:
      type: apiKey
      in: cookie
      name: app-session

````