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

# Registers your close-lobby callback URL.

> Registers the https URL BluMint calls to tell you to close a lobby you
created that BluMint no longer needs: the host decided the match,
started it themselves or took it over to run it manually, a reset
cleared it, or the match was deleted. Registration is optional but
recommended. With a close URL, BluMint waits for your 200 to each
close before it asks you for a new lobby for any player in the closed
one, so no player is ever in two of your lobbies at once. Without
one, BluMint sends you no closes and does not wait, so a create can
identify a player whose earlier lobby is still open on your side, and you
expire such lobbies yourself. Registering again replaces the
previous URL. The URL's host must resolve only to public addresses,
an IP-address host must be a public IPv4 address, and BluMint follows
no redirects, so the URL must answer directly.

Which answer to send when BluMint calls your URL:

| Situation | Status | What happens next |
| --- | --- | --- |
| You closed the lobby, it had already ended, or you made no lobby under the key and will refuse one | `200` | The player's next match is created. |
| You are down or overloaded | `502`, `503`, `504`, `408`, `429`, or no answer | The player's next match waits while BluMint re-sends the close every 60 seconds, or once the wait your Retry-After names has passed when that is later, waiting at most 5 minutes, for up to 30 minutes, then goes to the host. |

For what BluMint sends to your URL and how to answer it, see [Close a lobby](/guide/close-a-lobby).



## OpenAPI

````yaml /openapi.json post /tournaments/match/setClose
openapi: 3.0.1
info:
  title: BluMint game partner API
  version: 2.0.0
  description: >-
    Reference for the endpoints your game uses to run BluMint tournaments. For
    the walkthrough, see the [game integration guide](https://docs.blumint.com).
    To request an API key, fill in the [game partner setup
    form](https://staging.blumint.io/contact/game-partner), and for a question,
    [contact BluMint](https://staging.blumint.io/contact).
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
servers:
  - description: Staging, for building and testing
    url: https://staging.blumint.io/api
  - description: Production
    url: https://app.blumint.com/api
security:
  - ApiKeyAuth: []
tags: []
paths:
  /tournaments/match/setClose:
    post:
      tags:
        - Tournaments
      summary: Registers your close-lobby callback URL.
      description: >-
        Registers the https URL BluMint calls to tell you to close a lobby you

        created that BluMint no longer needs: the host decided the match,

        started it themselves or took it over to run it manually, a reset

        cleared it, or the match was deleted. Registration is optional but

        recommended. With a close URL, BluMint waits for your 200 to each

        close before it asks you for a new lobby for any player in the closed

        one, so no player is ever in two of your lobbies at once. Without

        one, BluMint sends you no closes and does not wait, so a create can

        identify a player whose earlier lobby is still open on your side, and
        you

        expire such lobbies yourself. Registering again replaces the

        previous URL. The URL's host must resolve only to public addresses,

        an IP-address host must be a public IPv4 address, and BluMint follows

        no redirects, so the URL must answer directly.


        Which answer to send when BluMint calls your URL:


        | Situation | Status | What happens next |

        | --- | --- | --- |

        | You closed the lobby, it had already ended, or you made no lobby under
        the key and will refuse one | `200` | The player's next match is
        created. |

        | You are down or overloaded | `502`, `503`, `504`, `408`, `429`, or no
        answer | The player's next match waits while BluMint re-sends the close
        every 60 seconds, or once the wait your Retry-After names has passed
        when that is later, waiting at most 5 minutes, for up to 30 minutes,
        then goes to the host. |


        For what BluMint sends to your URL and how to answer it, see [Close a
        lobby](/guide/close-a-lobby).
      operationId: setCloseMatch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - closeMatchUrl
              properties:
                closeMatchUrl:
                  type: string
                  format: uri
                  description: The https URL of your close-lobby endpoint.
                  example: https://www.yourgame.com/api/match/close
                authentication:
                  description: >-
                    The secret BluMint sends when it calls your close-lobby
                    endpoint. When omitted, any secret registered earlier stays
                    in place.
                  allOf:
                    - $ref: '#/components/schemas/CallbackAuthentication'
      responses:
        '200':
          description: The close-lobby callback URL is registered.
          content:
            application/json:
              schema:
                type: object
                required:
                  - message
                properties:
                  message:
                    type: string
                    example: Success - Match close callback URL set successfully.
        '400':
          $ref: '#/components/responses/CallbackRegistrationRefused'
        '401':
          $ref: '#/components/responses/CallbackRegistrationUnauthenticated'
        '404':
          $ref: '#/components/responses/CallbackRegistrationGameNotFound'
        '405':
          $ref: '#/components/responses/CallbackRegistrationMethodNotAllowed'
      callbacks:
        matchClose:
          '{$request.body#/closeMatchUrl}':
            post:
              description: |-
                Close the lobby and answer 200. BluMint identifies the lobby
                by the Idempotency-Key of the create that made it, including a
                create whose answer BluMint never received or that was still
                in flight when its match was decided. Close the lobby you made
                under that key, and when you made none, record the key as
                closed, answer 200, and refuse a later create under it with
                409 idempotency_key_reused: a create under that key can still
                reach you after the close, and a lobby made from it would have
                no players and might never be closed. A close takes the same
                per-key reservation as a create: when a create under the key
                is still building, record the key closed and answer 200, and
                that create re-reads the mark before it commits its lobby,
                tears down what it built and answers 409
                idempotency_key_reused. A lobby that already
                ended answers 200 too, including one whose key you no longer
                keep. Close the lobby and answer 200 whatever the reason,
                including one you do not recognize. Keep each
                create's key for as long as you keep the lobby it made, so a
                close can always find it. The same close can arrive more than
                once, always under the same Idempotency-Key. BluMint stops
                waiting after 10 seconds and treats a timeout as no answer,
                the outage row of the decision table above. A Retry-After wait
                reaching past the re-send window is cut short, so one last
                close is sent.

                That table lists every answer BluMint acts on. A key you hold
                nothing under is the 200 row, never a 404. When your server
                is down only for a while, answer 503 or another status on the
                outage row, so BluMint re-sends the close. BluMint reads any
                answer the table does not list, a 404 or a 500 included, as
                a failed close, since it can't tell whether the lobby is still
                open with players in it, and every match waiting on it goes
                to the host. Once a close's matches have gone to the host,
                BluMint never sends that close again: treat the lobby as
                closed and expire it, so a later create identifying its
                players never meets player_busy.
              parameters:
                - name: Idempotency-Key
                  in: header
                  required: true
                  description: >-
                    An opaque value BluMint derives for each close, the same on
                    every delivery of it: close-key- followed by the create's
                    Idempotency-Key. It holds only ASCII letters, digits and -,
                    and can be longer than a create's key.
                  schema:
                    type: string
                    pattern: ^[A-Za-z0-9-]+$
                  example: close-key-tA1b2-round-1-match-1
              requestBody:
                required: true
                content:
                  application/json:
                    schema:
                      type: object
                      required:
                        - idempotencyKey
                        - reason
                      properties:
                        idempotencyKey:
                          allOf:
                            - $ref: '#/components/schemas/PartnerCreateIdempotencyKey'
                          description: >-
                            The Idempotency-Key of the create that made the
                            lobby to close, never your matchId. It can belong to
                            a create whose answer never reached BluMint, or to
                            one that never reached you.
                        reason:
                          $ref: '#/components/schemas/PartnerCloseReason'
                    examples:
                      decided:
                        summary: A lobby whose match the host decided
                        value:
                          idempotencyKey: tA1b2-round-1-match-1
                          reason: decided
                      removed:
                        summary: >-
                          A match deleted before its create's answer reached
                          BluMint
                        value:
                          idempotencyKey: tA1b2-round-1-match-1
                          reason: removed
              responses:
                '200':
                  description: >-
                    The lobby is closed or had already ended, or no lobby exists
                    under the key and you will refuse a create under it.
              method: post
              type: path
            path: '{$request.body#/closeMatchUrl}'
      security:
        - ApiKeyAuth: []
components:
  schemas:
    CallbackAuthentication:
      type: object
      required:
        - secret
        - config
      properties:
        secret:
          type: string
          description: >-
            A value you choose, which BluMint sends to your server so you can
            tell the call came from BluMint. It is not your BluMint API key, so
            never put that key here. Use a long random value.
          example: your-inbound-secret
        config:
          type: object
          description: >-
            Where BluMint puts the secret. It sends valuePrefix, then the
            secret, then valueSuffix, under the name in key. In a header, that
            value may hold only tabs and Latin-1 characters from U+0020 through
            U+00FF other than DEL (U+007F), and cannot start or end with a space
            or tab, which your server's HTTP parser strips, so trim the newline
            or space a secret read from a file often ends in. BluMint refuses
            any other header value with 400.
          required:
            - location
            - key
          properties:
            location:
              type: string
              enum:
                - header
                - queryParam
                - body
              description: >-
                header sends the secret as a request header, and queryParam as a
                query parameter. body puts it into every POST body BluMint sends
                this URL as a top-level field: check that field, then remove it
                before you read or validate the rest of the body, and, on a
                callback that carries an Idempotency-Key, before you compare a
                request with an earlier one under the same key.
              example: header
            key:
              type: string
              description: >-
                The header name, query parameter or body field that carries the
                secret. BluMint refuses the registration with 400, quoting the
                key and saying whether it is a header or a body field, when the
                key names something it already sends this callback in the same
                place: a body field such as `teams`, any sign-in method field a
                player lookup can carry (`discord`, `epic`, `twitch` and
                `lichess`, even one your game does not use), the
                `Idempotency-Key` header, or a header every BluMint POST carries
                (`Accept`, `Accept-Encoding`, `Connection`, `Content-Length`,
                `Content-Type`, `Host` and `User-Agent`). Header names match in
                any case, and body fields exactly. A header key must be a valid
                HTTP header name, one or more letters, digits or characters from
                `!#$%&'*+-.^_|~` or the backtick, with no spaces, and cannot be
                `common`, `delete`, `expect`, `get`, `head`, `patch`, `post`,
                `put`, `trailer`, `transfer-encoding` or `__proto__` in any
                case, names BluMint's HTTP client reserves. A body key cannot be
                a built-in JavaScript object property name such as
                `constructor`, `toString` or `__proto__`. A query parameter key
                may be any string. A name such as `blumint_secret` passes every
                rule.
              example: Authorization
            valuePrefix:
              type: string
              description: Text BluMint sends before the secret, such as "Bearer ".
              example: 'Bearer '
            valueSuffix:
              type: string
              description: Text BluMint sends after the secret.
    PartnerCreateIdempotencyKey:
      type: string
      maxLength: 128
      pattern: ^[A-Za-z0-9-]{1,128}$
      description: >-
        The Idempotency-Key BluMint sent with the create that made the lobby,
        exactly as sent: at most 128 ASCII letters, digits and -. Treat it as
        opaque and never parse it.
    PartnerCloseReason:
      type: string
      enum:
        - decided
        - replaced
        - removed
        - hostOverride
      description: |-
        Why BluMint is closing your lobby. Close it and answer 200 whatever
        the reason; the reason is for your logs.

        - decided: the BluMint match, or a game session of it, got a result
          without you, for example because the host entered a score.
        - replaced: something other than the host's take over replaced the
          lobby you made. BluMint handed the match to the host (your create
          failed for good after you may have made a lobby: a 500, a 409
          idempotency_key_reused, a 200 it could not use, an answer the
          decision table does not list, or an outage on its last send; or
          its hold ran out) and the host then set it up; the host set it up
          while your create was still on its way; the host reset its score;
          a player change re-seated it; or you made a second lobby under
          one Idempotency-Key.
        - removed: the BluMint match was deleted, for example because the
          host undid the start of the tournament.
        - hostOverride: the host pressed take over on a match you were
          running or setting up, to run it manually instead.
  responses:
    CallbackRegistrationRefused:
      description: >-
        The URL is missing, is not a valid absolute URL or is not https,
        contains a user name or password (`user:pass@`), has an IP-address host
        other than a public IPv4 address, the authentication block is malformed,
        its header key or value is not a valid HTTP header name or value, its
        header key is a name BluMint's HTTP client reserves, its body key is a
        built-in JavaScript object property name, or its key names a header or
        body field BluMint already sends this callback, which for a lookup is
        every sign-in method field a lookup can carry. A refusal of the key
        quotes it and says whether it is a header or a body field.
    CallbackRegistrationUnauthenticated:
      description: The X-Api-Key header is missing or unknown.
    CallbackRegistrationGameNotFound:
      description: The API key is bound to no game, or its game does not exist.
    CallbackRegistrationMethodNotAllowed:
      description: The method is not POST.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-Api-Key

````

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