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

# Buy extra credits for a partner

> Asks Widgetic for an invoice for extra credits, on top of the credits of the contract. Name the dollars; the
invoice is for the most whole credits they buy at the **list price** of a credit (the price a contract may
lower belongs to the contract), so it is never for more than you asked: 12.34 buys 123 credits and the invoice
says 12.30. The smallest purchase is 10 dollars and one request buys at most 100000 (ask Widgetic for an
invoice for more).

Pay the invoice with the link in the answer. When it is paid the credits are added **once, for good**, to the
account of the person who administers the partner, which is the account everything the partner builds is
charged to (`getPartnerCreditBalance` shows it). Extra credits **do not expire**, unlike the credits of a
contract period, which end with it. Nothing is added before the invoice is paid, and an unpaid invoice for
extra credits never stops the partner: only an unpaid invoice of the contract does (`payment_arrears`).

Available only to partners that have an active paid contract in force with Widgetic (`NO_PAID_CONTRACT` when
none is in force) and no overdue contract invoice (`CONTRACT_INVOICE_OVERDUE` while a contract invoice is past
its due day). A partner that has run out of credits during its period can buy more at the list price.

An `Idempotency-Key` is required, and it is what makes a retry safe: the same key with the same body returns
the invoice already issued, the same key with a different body is refused with 422, and a duplicate that
arrives while the first is still running is refused with 409. Use one key per purchase you mean to make, and
a new key for the next one. At most 10 requests an hour.

Who may ask: the person who administers the partner, or a Widgetic administrator. A key limited to scopes
needs `billing:write`.




## OpenAPI

````yaml /openapi/widgetic-api-public.json post /partners/{partnerId}/credits/extra-invoice
openapi: 3.0.0
info:
  title: Widgetic API Gateway
  version: 1.0.0
  description: API documentation for the Widgetic API Gateway
  license:
    name: Widgetic Integration License
    url: https://docs.widgetic.com/resources/license
servers:
  - url: https://api.widgetic.com/v1
    description: Production server
    variables:
      env:
        default: production
        description: Environment
      apiUrl:
        default: https://api.widgetic.com
        description: API URL
      apiVersion:
        default: /v1
        description: API Version path prefix
security: []
tags: []
paths:
  /partners/{partnerId}/credits/extra-invoice:
    post:
      tags:
        - Partners
      summary: Buy extra credits for a partner
      description: >
        Asks Widgetic for an invoice for extra credits, on top of the credits of
        the contract. Name the dollars; the

        invoice is for the most whole credits they buy at the **list price** of
        a credit (the price a contract may

        lower belongs to the contract), so it is never for more than you asked:
        12.34 buys 123 credits and the invoice

        says 12.30. The smallest purchase is 10 dollars and one request buys at
        most 100000 (ask Widgetic for an

        invoice for more).


        Pay the invoice with the link in the answer. When it is paid the credits
        are added **once, for good**, to the

        account of the person who administers the partner, which is the account
        everything the partner builds is

        charged to (`getPartnerCreditBalance` shows it). Extra credits **do not
        expire**, unlike the credits of a

        contract period, which end with it. Nothing is added before the invoice
        is paid, and an unpaid invoice for

        extra credits never stops the partner: only an unpaid invoice of the
        contract does (`payment_arrears`).


        Available only to partners that have an active paid contract in force
        with Widgetic (`NO_PAID_CONTRACT` when

        none is in force) and no overdue contract invoice
        (`CONTRACT_INVOICE_OVERDUE` while a contract invoice is past

        its due day). A partner that has run out of credits during its period
        can buy more at the list price.


        An `Idempotency-Key` is required, and it is what makes a retry safe: the
        same key with the same body returns

        the invoice already issued, the same key with a different body is
        refused with 422, and a duplicate that

        arrives while the first is still running is refused with 409. Use one
        key per purchase you mean to make, and

        a new key for the next one. At most 10 requests an hour.


        Who may ask: the person who administers the partner, or a Widgetic
        administrator. A key limited to scopes

        needs `billing:write`.
      operationId: createPartnerExtraCreditsInvoice
      parameters:
        - in: path
          name: partnerId
          required: true
          schema:
            type: string
            format: uuid
          description: Partner ID
        - in: header
          name: Idempotency-Key
          required: true
          schema:
            type: string
            minLength: 8
            maxLength: 50
            pattern: ^[A-Za-z0-9_-]+$
          description: >-
            A key of your own for this purchase, so that a retry cannot make a
            second invoice
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RequestExtraCredits'
      responses:
        '200':
          description: The invoice was issued
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerExtraCreditsInvoiceResponse'
        '400':
          description: >-
            The amount is not a number of dollars and cents, is under 10 or over
            100000, or the Idempotency-Key header is missing or malformed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Not authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: The caller does not administer this partner
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: >-
            There is no such partner (a Widgetic administrator asked for an id
            that does not exist)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Another request with this Idempotency-Key is still running
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: >-
            This Idempotency-Key was already used with a different body, the
            partner has no active paid contract (`NO_PAID_CONTRACT`), the
            partner owes an overdue contract invoice
            (`CONTRACT_INVOICE_OVERDUE`), the partner has no administrator
            account to add the credits to (`NO_PARTNER_ADMINISTRATOR`), there is
            no billing email and no contact email to send the invoice to
            (`NO_BILLING_EMAIL`), or Stripe did not accept the tax ID on the
            billing profile (`TAX_ID_INVALID`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Too many requests; at most 10 an hour
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: >-
            Stripe could not issue the invoice. Nothing was sent; retry with the
            same Idempotency-Key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - apiKeyAuth: []
components:
  schemas:
    RequestExtraCredits:
      type: object
      required:
        - usd
      properties:
        usd:
          type: number
          minimum: 10
          maximum: 100000
          description: >
            The dollars to spend on credits, to the cent: at least 10, at most
            100000 in one request. The invoice is for the most whole credits
            that money buys at the list price of a credit, so it is never for
            more than this (12.34 buys 123 credits and the invoice says 12.30).
          example: 250
      example:
        usd: 250
    PartnerExtraCreditsInvoiceResponse:
      type: object
      required:
        - success
        - data
      properties:
        success:
          type: boolean
          description: Always `true` on a success.
          example: true
        data:
          $ref: '#/components/schemas/PartnerExtraCreditsInvoice'
        meta:
          $ref: '#/components/schemas/ResponseMeta'
    ErrorResponse:
      type: object
      required:
        - success
        - message
        - error
      additionalProperties: true
      properties:
        success:
          type: boolean
          description: Always `false` on a failure.
          example: false
        message:
          type: string
          description: The same text as `error.message`, for a caller that reads one line.
        error:
          $ref: '#/components/schemas/ErrorDetail'
    PartnerExtraCreditsInvoice:
      type: object
      description: The invoice for extra credits that was issued, and what paying it adds.
      required:
        - invoiceId
        - number
        - hostedInvoiceUrl
        - pdfUrl
        - credits
        - creditPriceUsd
        - amountUsd
        - taxUsd
        - totalUsd
        - currency
        - dueDate
        - dueDays
      properties:
        invoiceId:
          type: string
          description: Stripe's id for the invoice.
        number:
          type: string
          nullable: true
          description: The number printed on the invoice, once Stripe has numbered it.
        hostedInvoiceUrl:
          type: string
          format: uri
          nullable: true
          description: The page where the invoice is viewed and paid.
        pdfUrl:
          type: string
          format: uri
          nullable: true
          description: A PDF of the invoice.
        credits:
          type: integer
          description: >-
            The credits paying the invoice adds, once and for good. They do not
            expire.
        creditPriceUsd:
          type: number
          description: >-
            What one credit costs, in dollars. It is the list price, not the
            price of the contract.
        amountUsd:
          type: number
          description: >-
            The price of those credits, in dollars, before tax. Never more than
            `usd` of the request.
        taxUsd:
          type: number
          description: The tax added to the invoice, in dollars (0 when there is none).
        totalUsd:
          type: number
          description: What is paid, in dollars. The price plus the tax.
        currency:
          type: string
          description: The currency of the invoice, in upper case (USD).
        dueDate:
          type: string
          format: date-time
          nullable: true
          description: When payment is due, as printed on the invoice.
        dueDays:
          type: integer
          description: How many days there are to pay.
      example:
        invoiceId: Example invoiceId
        number: Example number
        hostedInvoiceUrl: Example hostedInvoiceUrl
        pdfUrl: Example pdfUrl
        credits: 42
        creditPriceUsd: 42
        amountUsd: 42
        taxUsd: 42
        totalUsd: 42
        currency: Example currency
        dueDate: '2026-01-15T09:30:00.000Z'
        dueDays: 42
    ResponseMeta:
      type: object
      description: >-
        Extra information about the answer: where a page sits in a list, the
        cursor of the next page, or warnings about a call that succeeded with a
        caveat.
      additionalProperties: true
      properties:
        page:
          type: integer
          description: The page that was read, counting from 1.
          example: 1
        size:
          type: integer
          description: How many items one page holds.
          example: 20
        total:
          type: integer
          description: How many items the whole list has.
          example: 135
        limit:
          type: integer
          description: The same as `size`.
          example: 20
        offset:
          type: integer
          description: How many items come before this page.
          example: 0
        hasNextPage:
          type: boolean
          example: true
        hasPreviousPage:
          type: boolean
          example: false
        nextCursor:
          type: string
          nullable: true
          description: >-
            Pass this as `cursor` to read the next page of a list that is read
            by cursor. `null` on the last page.
        warnings:
          type: array
          items:
            type: string
          description: >-
            Things the call did not do, though it succeeded (for example a table
            that could not be created just now).
    ErrorDetail:
      type: object
      required:
        - code
        - message
        - timestamp
      properties:
        code:
          type: string
          description: Machine-readable error code.
          example: RESOURCE_NOT_FOUND
        message:
          type: string
          description: Human-readable explanation.
          example: Composition not found
        param:
          type: string
          description: The field that caused the error, when one did.
          example: name
        docUrl:
          type: string
          description: Where this error is explained.
        suggestedAction:
          type: string
          description: What to do about it.
        retryAfter:
          type: integer
          description: >-
            Seconds to wait before trying again (rate limits). The same number
            is in the `Retry-After` header.
          example: 60
        details:
          type: object
          additionalProperties: true
          description: >-
            More about the error: the fields that failed, a limit that was
            reached.
        correlationId:
          type: string
          description: Quote this when you ask support about the call.
          example: req_123e4567-e89b-12d3-a456-426614174000
        timestamp:
          type: string
          format: date-time
          example: '2026-10-15T10:00:00.000Z'
  securitySchemes:
    apiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.