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

# Free a machine's seat

> Idempotent · deactivating an already-deactivated instance succeeds and returns it. Only an instance that never existed on this licence is a `404`.



## OpenAPI

````yaml /v3-beta/api-reference/openapi.yaml post /v3/licenses/deactivate
openapi: 3.1.0
info:
  title: Suby.fi Merchant API
  version: 3.0.0-beta
  description: >
    The **v3** public merchant API for Suby.fi. RESTful (plural,
    resource-oriented

    endpoints under the `/v3` prefix). Authenticate every request

    with your secret API key in the `X-Suby-Api-Key` header.


    - `sk_live_…` keys operate in **production** (real funds).

    - `sk_sandbox_…` keys operate in a fully simulated **sandbox** (test cards,
      Base Sepolia crypto, no real money). The environment is derived from the
      key prefix.
  contact:
    email: contact@suby.fi
    url: https://suby.fi
servers:
  - url: https://api.beta.suby.fi
    description: Production + sandbox (environment selected by API key prefix)
security:
  - ApiKeyAuth: []
tags:
  - name: Products
    description: Manage your product catalog (one-time and recurring).
  - name: Checkout
    description: >-
      Hosted checkout · signed session tokens (`cs_…`). Every card Suby holds
      was collected here, which is what keeps card data out of your systems.
  - name: Payments
    description: >-
      Read payments and receipts, refund them, and debit a stored instrument
      off-session (pay-as-you-go). Collecting a card happens on the hosted
      checkout, never here.
  - name: Subscriptions
    description: >-
      Drive a live subscription · read it, change its plan, end it.
      Subscriptions are opened by a checkout session, not by this API.
  - name: Discount Codes
    description: Promo codes, redeemed at checkout.
  - name: Crypto
    description: >-
      The headless rail · quote, charge, and settle on-chain from inside your
      own site. No card data is involved, so none of the constraints that keep
      card collection on a Suby page apply here.
  - name: Customers
    description: First-class customer records with billing address.
  - name: Payment Methods
    description: >-
      Read and detach the cards a customer has stored. They are created by a
      checkout session (`savePaymentMethod`, or `mode=setup`) · the only place a
      card is collected.
  - name: Licence Key
    description: >-
      The licence server · validate a key, take a seat, free one. Authenticated
      with your API key like everything else, and scoped to the licences you
      issued, so your backend relays the check rather than your customer's
      software calling it directly.
paths:
  /v3/licenses/deactivate:
    post:
      tags:
        - Licence Key
      summary: Free a machine's seat
      description: >-
        Idempotent · deactivating an already-deactivated instance succeeds and
        returns it. Only an instance that never existed on this licence is a
        `404`.
      operationId: deactivateLicense
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - key
                - instanceId
              properties:
                key:
                  type: string
                instanceId:
                  type: string
                  description: The id `activate` returned in `instance.id`.
      responses:
        '200':
          description: The licence, with the freed instance
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/License'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: LICENSE_NOT_FOUND or LICENSE_INSTANCE_NOT_FOUND
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: >-
        Optional key (≤255 chars, e.g. a UUID v4) that makes this POST safe to
        retry: the first request executes and its response is cached for 24h; a
        retry with the SAME key replays that response instead of re-executing
        (no duplicate payment/subscription). A reused key with a different
        request → `422 IDEMPOTENCY_KEY_CONFLICT`; a retry while the first is
        still in flight → `409`. See the Idempotency guide.
      schema:
        type: string
        maxLength: 255
        example: 5f3b9c2e-1a4d-4f2b-9c31-7e2a1b6d8c04
  schemas:
    License:
      allOf:
        - $ref: '#/components/schemas/SuccessEnvelope'
        - type: object
          properties:
            data:
              type: object
              properties:
                id:
                  type: string
                  example: lic_abc123
                productId:
                  type: string
                  nullable: true
                  description: >-
                    The product this licence was sold with, when the sale
                    carried one.
                customerId:
                  type: string
                  example: cus_abc123
                status:
                  type: string
                  enum:
                    - active
                    - inactive
                    - expired
                    - disabled
                  description: >-
                    `active` · good to run. `inactive` · issued but never
                    claimed by the buyer. `expired` · past its expiry, or the
                    grant behind it lapsed. `disabled` · revoked: refunded,
                    charged back, or cut off by you.
                keyLast4:
                  type: string
                  description: >-
                    Last four characters of the key. The key itself is never
                    echoed · you already hold it, and a secret in a response
                    body is a secret in every log.
                activation:
                  type: integer
                  description: Seats currently taken.
                activationLimit:
                  type: integer
                  nullable: true
                  description: Seat cap, or null for unlimited.
                expiresAt:
                  type: string
                  format: date-time
                  nullable: true
                createdAt:
                  type: string
                  format: date-time
                sandbox:
                  type: boolean
                instance:
                  nullable: true
                  description: >-
                    The instance this call concerned · the one activated, the
                    one deactivated, or the one named on a validate. Null when
                    the call named none.
                  type: object
                  properties:
                    id:
                      type: string
                      description: Minted by Suby at activation. Store it; send it back.
                    name:
                      type: string
                      nullable: true
                    status:
                      type: string
                      enum:
                        - active
                        - deactivated
                    createdAt:
                      type: string
                      format: date-time
    SuccessEnvelope:
      type: object
      required:
        - success
        - data
      properties:
        success:
          type: boolean
          example: true
        message:
          type: string
        data:
          description: Endpoint-specific payload.
    Error:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          example: false
        error:
          type: string
          description: Machine-readable error code.
          example: NOT_FOUND
        message:
          type: string
          example: Resource not found
        data:
          description: Optional error detail.
  responses:
    Unauthorized:
      description: Invalid or missing API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            success: false
            error: UNAUTHORIZED
            message: Invalid or missing API key
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-Suby-Api-Key
      description: Secret API key. `sk_live_…` (production) or `sk_sandbox_…` (sandbox).

````