Playable API

Public REST API for the Playable gamification platform. Covers campaign types, campaign lifecycle (list, view, update, copy, delete, activate, pause, resume, clear cache), campaign sections and registration form fields, prizes and bulk prizes, vouchers, player registrations, email and SMS logs, game data statistics, session/registration analytics, game settings, media upload and login-token creation. OAuth 2.0 client-credentials with 37 fine-grained scopes; 3,600 requests per hour per developer app with X-RateLimit-* and Retry-After response headers.

OpenAPI Specification

playable-api-openapi.yml Raw ↑
openapi: 3.0.0
info:
  title: Swagger with Laravel
  description: |
    This documentation aims to provide all the information you need to work with our API.

    ***Rate limiting***

    APIs are bound by rate limiting. The default rate limiting allows for 3.600 API interactions an hour per developer app (not IP).
    You are **NOT** allowed to attempt by-pass of rate limiting by creating multiple apps and distribute your traffic across these.
    If an API has a different rate limit it will be described in the description of the API.

    ***Every API response contains 2 extra headers***
    1. `X-RateLimit-Limit` max number of requests you can do in the defined period.
    2. `X-RateLimit-Remaining` how many requests you have left before hitting the rate limit.

    ***Required Headers***
    1. `Authorization` used to provide credentials that authenticate an application.
    2. `Accept` specifies the response type. Only "application/json" is supported.

    Once you've hit your rate limit the response will also include `Retry-After`. This will be the seconds in which you will have to wait for doing additional API requests.

    ***Throughout***
    The API is designed to allow 3.600 requests per hour per developer app. This is a hard limit and cannot be increased.

    ***Caching***
    Playable *expect* implementations to be mindful of not overloading the API with requests.
    Playable **expect** implementations to cache data where possible and only request data when it's needed.
    If you're found to be abusing the API by not caching data, you may be subject to rate limiting or have your access revoked.
  version: 1.0.0
paths:
  /oauth/token:
    post:
      tags:
        - oauth
      summary: Authentication
      description: |
        ***Authenticating requests***

        To authenticate requests, include an **`Authorization`** header with the value **`"Bearer {{ACCESS_TOKEN}}"`**.

        All authenticated endpoints are marked with a `requires authentication` badge in the documentation below.

        You can create your own app to gain API access under __Global settings__ / __Developer apps__.

        * campaigns.list
        * campaigns.view
        * campaigns.pause
        * campaigns.resume
        * campaigns.integrations.list
        * campaigns.game-data-statistics
        * campaigns.sections.list
        * campaigns.sections.view
        * campaigns.sections.form-fields.list
        * campaigns.sections.form-fields.view
        * campaigns.prizes.list
        * campaigns.prizes.view
        * campaigns.bulk-prizes.list
        * campaigns.bulk-prizes.view
        * campaigns.bulk-prizes-items.send-email
        * campaigns.email-log.list
        * campaigns.email-log.view
        * campaigns.sms-log.list
        * campaigns.sms-log.view
        * campaigns.registrations.list
        * campaigns.registrations.view
        * campaigns.registrations.delete
        * campaigns.voucher.list
        * campaigns.voucher.view
        * campaigns.voucher.delete
        * campaigns.types.list
        * campaigns.types.view
        * campaigns.copy
        * campaigns.clear-cache
        * media.upload
        * user.create-login-token

        ***Issue Token***

        This API issues a new access token. List over available scopes can be seen under the authentication introduction.
        Access tokens have a life-span of 1 hour. Once expired you will have to generate a new access token.
        We expect implementations to re-use access tokens generated for as long as they're active.

        Applications found to be generating new access tokens when existing ones haven't expired may be subject to rate limiting.
        Scope can be declared singular as string or multiple as array within a single request.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              required:
                - grant_type
                - client_id
                - client_secret
              properties:
                grant_type:
                  description: The type of grant being requested
                  type: string
                  example: client_credentials
                client_id:
                  description: The client ID issued to the client
                  type: string
                  example: your-client-id
                client_secret:
                  description: The client secret issued to the client
                  type: string
                  example: your-client-secret
                scope:
                  description: Scopes allowed to interact with
                  type: array
                  items:
                    type: string
                    enum:
                      - campaigns.list
                      - campaigns.view
                      - campaigns.pause
                      - campaigns.resume
                      - campaigns.integrations.list
                      - campaigns.game-data-statistics
                      - campaigns.sections.list
                      - campaigns.sections.view
                      - campaigns.sections.form-fields.list
                      - campaigns.sections.form-fields.view
                      - campaigns.prizes.list
                      - campaigns.prizes.view
                      - campaigns.bulk-prizes.list
                      - campaigns.bulk-prizes.view
                      - campaigns.bulk-prizes-items.send-email
                      - campaigns.email-log.list
                      - campaigns.email-log.view
                      - campaigns.sms-log.list
                      - campaigns.sms-log.view
                      - campaigns.registrations.list
                      - campaigns.registrations.view
                      - campaigns.registrations.delete
                      - campaigns.voucher.list
                      - campaigns.voucher.view
                      - campaigns.voucher.delete
                      - campaigns.types.list
                      - campaigns.types.view
                      - campaigns.copy
                      - campaigns.clear-cache
                      - media.upload
                      - user.create-login-token
                  example:
                    - campaigns.list
                    - campaigns.view
                    - campaigns.pause
                    - campaigns.resume
                    - campaigns.integrations.list
                    - campaigns.game-data-statistics
                    - campaigns.sections.list
                    - campaigns.sections.view
                    - campaigns.sections.form-fields.list
                    - campaigns.sections.form-fields.view
                    - campaigns.prizes.list
                    - campaigns.prizes.view
                    - campaigns.bulk-prizes.list
                    - campaigns.bulk-prizes.view
                    - campaigns.bulk-prizes-items.send-email
                    - campaigns.email-log.list
                    - campaigns.email-log.view
                    - campaigns.sms-log.list
                    - campaigns.sms-log.view
                    - campaigns.registrations.list
                    - campaigns.registrations.view
                    - campaigns.registrations.delete
                    - campaigns.voucher.list
                    - campaigns.voucher.view
                    - campaigns.voucher.delete
                    - campaigns.types.list
                    - campaigns.types.view
                    - campaigns.copy
                    - campaigns.clear-cache
                    - media.upload
                    - user.create-login-token
              type: object
      responses:
        '200':
          description: Issue token to api
          content:
            application/json:
              schema:
                properties:
                  token_type:
                    type: string
                    example: token_type
                  expires_in:
                    type: integer
                    example: '3600'
                  access_token:
                    type: string
                    example: token
                type: object
        '400':
          description: Invalid request
        '401':
          description: |
            Unauthorized.

            Possible reasons:
            Token has expired
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: 'message": "Unauthenticated.'
  /v1/campaign-types:
    get:
      tags:
        - campaigns
      summary: Campaign types
      description: |
        List all campaign types
        This API lists all campaign types in the system.

        Requires scope:

        `campaigns.types.list`
      security:
        - clientCredentials:
            - campaigns.types.list
      parameters:
        - name: filter_category
          in: query
          description: 'Filter for campaign type category. Available options are: luck, skill, knowledge.'
          required: false
          schema:
            type: string
            enum:
              - luck
              - skill
              - knowledge
      responses:
        '200':
          description: Lists all campaign types available in the system
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      properties:
                        id:
                          type: integer
                        name:
                          type: string
                          example: Quiz
                        alias:
                          type: string
                          example: quiz
                        variation:
                          type: string
                          example: GAME
                        description:
                          type: string
                        category:
                          type: string
                          example: Knowledge games
                      type: object
                  links:
                    properties:
                      self:
                        type: string
                        example: 'https://api.playable.com/v1/campaigns-types'
                    type: object
        '401':
          description: |
            Unauthorized.

            Possible reasons:
            Token has expired
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: 'message": "Unauthenticated.'
  '/v1/campaign-type/{campaignType}':
    get:
      tags:
        - campaigns
      summary: |
        This API responds with a single campaign type resource.

        Requires scope:

        `campaigns.types.view`
      security:
        - clientCredentials:
            - campaigns.types.view
      parameters:
        - name: campaignType
          in: path
          description: campaignType id
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Retrieve a single campaign type by id
          content:
            application/json:
              schema:
                properties:
                  data:
                    properties:
                      id:
                        type: integer
                      name:
                        type: string
                        example: Quiz
                      alias:
                        type: string
                        example: quiz
                      variation:
                        type: string
                        example: GAME
                      description:
                        type: string
                      category:
                        type: string
                        example: Knowledge games
                    type: object
                type: object
        '401':
          description: |
            Unauthorized.

            Possible reasons:
            Token has expired
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: 'message": "Unauthenticated.'
        '403':
          description: Unable to locate campaign type
  /v1/campaigns:
    get:
      tags:
        - campaigns
      summary: Campaigns list
      description: |
        This API lists all campaigns.

        Requires scope:

        `campaigns.list`
      security:
        - clientCredentials:
            - campaigns.list
      parameters:
        - name: sort
          in: query
          description: |
            Comma separated list which allows for multi-sorting.
            Available fields are: name, created_on.
            Available options are: asc, desc.
          required: false
          schema:
            type: string
        - name: filter_template
          in: query
          description: Filter for campaign templates.
          required: false
          schema:
            type: string
            enum:
              - 0
              - 1
        - name: filter_name
          in: query
          description: Filter for specific campaign by name.
          required: false
          schema:
            type: string
        - name: filter_type
          in: query
          description: Filter for specific campaign type by alias.
          required: false
          schema:
            type: string
        - name: filter_display
          in: query
          description: Filter for active or inactive campaigns.
          required: false
          schema:
            type: string
            enum:
              - active
              - inactive
        - name: with
          in: query
          required: false
          description: |
            Comma separated list of extra fields to include about the campaigns.
            Available options are:
            registrations, sessions, is_instant_win, has_data_wiped, integrations, sections,
            sections.form_fields, bulk_prizes & sections.sessions.
          schema:
            type: array
            items:
              type: string
              example: ''
        - name: page
          in: query
          required: false
          schema:
            type: integer
      responses:
        '200':
          description: Lists all campaigns available in the system
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      properties:
                        id:
                          type: integer
                        name:
                          type: string
                        timezone:
                          type: string
                          example: Europe/Copenhagen
                          description: 'Available timezones: [link](https://www.php.net/manual/en/timezones.php)'
                        type:
                          type: string
                        active:
                          type: boolean
                        active_from:
                          type: string
                          format: date-time
                        active_to:
                          type: string
                          format: date-time
                        live_url:
                          type: string
                        demo_url:
                          type: string
                        created_on:
                          type: string
                          format: date-time
                        template:
                          properties:
                            enabled:
                              type: boolean
                            image:
                              type: string
                          type: object
                        links:
                          properties:
                            self:
                              type: string
                            integrations:
                              type: string
                            sections:
                              type: string
                            prizes:
                              type: string
                            gameDataStatistics:
                              type: string
                            bulkPrizes:
                              type: string
                          type: object
                      type: object
                  links:
                    items:
                      title: base links
                      properties:
                        first:
                          type: string
                          example: 'https://api.playable.com/v1/route?page=1'
                        last:
                          type: string
                          example: 'https://api.playable.com/v1/route?page=14'
                        prev:
                          type: string
                          example: 'https://api.playable.com/v1/route?page=13'
                        next:
                          type: string
                          example: 'https://api.playable.com/v1/route?page=2'
                      type: object
                  meta:
                    items:
                      title: base meta
                      properties:
                        current_page:
                          type: integer
                        from:
                          type: integer
                        path:
                          type: string
                        per_page:
                          type: integer
                        to:
                          type: integer
                      type: object
        '401':
          description: |
            Unauthorized.

            Possible reasons:
            Token has expired
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: 'message": "Unauthenticated.'
  '/v1/campaign/{campaign}':
    get:
      tags:
        - campaigns
      summary: Show a single campaign
      description: |
        This API responds with a single campaign.

        Requires scope:

        `campaigns.view`
      security:
        - clientCredentials:
            - campaigns.view
      parameters:
        - name: campaign
          in: path
          description: Campaign id
          required: true
          schema:
            type: integer
        - name: with
          in: query
          description: Comma separated list of extra fields to include about the campaigns.
          required: false
          schema:
            type: string
            enum:
              - registrations
              - sessions
              - is_instant_win
              - has_data_wiped
              - integrations
              - sections
              - sections.form_fields
              - bulk_prizes
              - sections.sessions
      responses:
        '200':
          description: Show a single campaign
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    properties:
                      id:
                        type: integer
                      name:
                        type: string
                      timezone:
                        type: string
                        example: Europe/Copenhagen
                        description: 'Available timezones: [link](https://www.php.net/manual/en/timezones.php)'
                      type:
                        type: string
                      active:
                        type: boolean
                      active_from:
                        type: string
                        format: date-time
                      active_to:
                        type: string
                        format: date-time
                      live_url:
                        type: string
                      demo_url:
                        type: string
                      created_on:
                        type: string
                        format: date-time
                      template:
                        properties:
                          enabled:
                            type: boolean
                          image:
                            type: string
                        type: object
                      links:
                        properties:
                          self:
                            type: string
                          integrations:
                            type: string
                          sections:
                            type: string
                          prizes:
                            type: string
                          gameDataStatistics:
                            type: string
                          bulkPrizes:
                            type: string
                        type: object
                    type: object
        '401':
          description: |
            Unauthorized.

            Possible reasons:
            Token has expired
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: 'message": "Unauthenticated.'
    post:
      tags:
        - campaigns
      summary: Update Campaign
      description: |
        This API modifies and responds with an HTTP 204 - No Content. 

        Notice! minutes & seconds for active_from/to has to be 0.

        Requires scope:

        `campaigns.modify`
      security:
        - clientCredentials:
            - campaigns.modify
      parameters:
        - name: campaign
          in: path
          description: Campaign id
          required: true
          schema:
            type: integer
      requestBody:
        description: |
          name: The new name of the campaign.
          template_enabled: If the campaign should be a template. Either 0 or 1.
          template_image: Absolute path to the campaign template image.
          active_from: When the campaign should be active from. Date format: ISO-8601. Example: 2021-01-01T08:00:00+00:00
          active_to: When the campaign should end. Date format: ISO-8601. Example: 2021-01-01T08:00:00+00:00
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                template_enabled:
                  type: integer
                template_image:
                  type: string
                active_from:
                  type: string
                  format: datetime
                active_to:
                  type: string
                  format: datetime
              required:
                - name
      responses:
        '204':
          description: ''
        '401':
          description: |
            Unauthorized.

            Possible reasons:
            Token has expired
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: 'message": "Unauthenticated.'
    delete:
      tags:
        - campaigns
      summary: Delete Campaign
      description: |
        This API delete a campaign.

        Requires scope:

        `campaigns.delete`
      security:
        - clientCredentials:
            - campaigns.delete
      parameters:
        - name: campaign
          in: path
          description: Campaign id
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: ''
        '401':
          description: |
            Unauthorized.

            Possible reasons:
            Token has expired
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: 'message": "Unauthenticated.'
  '/v1/campaign/{campaign}/activate':
    post:
      tags:
        - campaigns
      summary: Activate Campaign
      description: |
        This API activates and responds with a single campaign resource.
        Notice! active_to cannot be further than the current subscription period & minutes/seconds for active_from/to has to be 0.

        Requires scope: 

        `campaigns.activate`
      security:
        - clientCredentials:
            - campaigns.activate
      parameters:
        - name: campaign
          in: path
          description: Campaign id
          required: true
          schema:
            type: integer
      requestBody:
        description: |
          active_from: When the campaign should be active from. Date format: ISO-8601. Example: 2021-01-01T08:00:00+00:00
          active_to: When the campaign should end. Date format: ISO-8601. Example: 2021-01-01T08:00:00+00:00
        content:
          application/json:
            schema:
              type: object
              properties:
                active_from:
                  type: string
                  format: datetime
                active_to:
                  type: string
                  format: datetime
              required:
                - active_from
                - active_to
      responses:
        '204':
          description: ''
        '401':
          description: |
            Unauthorized.

            Possible reasons:
            Token has expired
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: 'message": "Unauthenticated.'
  '/v1/campaign/{campaign}/pause':
    post:
      tags:
        - campaigns
      summary: Pause Campaign
      description: |
        This API pauses a campaign so that it is no longer active.

        This specific API has a rate limit of 1 call every minute.

        Requires scope:

        `campaigns.pause`
      security:
        - clientCredentials:
            - campaigns.pause
      parameters:
        - name: campaign
          in: path
          description: Campaign id
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: ''
        '401':
          description: |
            Unauthorized.

            Possible reasons:
            Token has expired
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: 'message": "Unauthenticated.'
  '/v1/campaign/{campaign}/resume':
    post:
      tags:
        - campaigns
      summary: Resume campaign
      description: |
        This API resumes a paused campaign so that it's active once more.

        This specific API has a rate limit of 1 call every minute.

        Requires scope:
        `campaigns.resume`
      security:
        - clientCredentials:
            - campaigns.resume
      parameters:
        - name: campaign
          in: path
          description: Campaign id
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: ''
        '401':
          description: |
            Unauthorized.

            Possible reasons:
            Token has expired
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: 'message": "Unauthenticated.'
  '/v1/campaign/copy/{campaign}':
    post:
      tags:
        - campaigns
      summary: Campaign copy
      description: |
        This API copies and responds with the copy of a campaign.

        This specific API has a rate limit of 10 calls every minute.

        Requires scope:

        `campaigns.copy`
      security:
        - clientCredentials:
            - campaigns.copy
      requestBody:
        description: |
          name: The name of the new campaign
          include_bulk_prizes: Should bulk prizes be copied over as well? 
          Default: false. Important: Only unlimited bulk prizes are copied over.
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                include_bulk_prizes:
                  type: boolean
              required:
                - name
                - include_bulk_prizes
      parameters:
        - name: campaign
          in: path
          description: Campaign id
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    properties:
                      id:
                        type: integer
                      name:
                        type: string
                      timezone:
                        type: string
                        example: Europe/Copenhagen
                        description: 'Available timezones: [link](https://www.php.net/manual/en/timezones.php)'
                      type:
                        type: string
                      active:
                        type: boolean
                      active_from:
                        type: string
                        format: date-time
                      active_to:
                        type: string
                        format: date-time
                      live_url:
                        type: string
                      demo_url:
                        type: string
                      created_on:
                        type: string
                        format: date-time
                      template:
                        properties:
                          enabled:
                            type: boolean
                          image:
                            type: string
                        type: object
                      links:
                        properties:
                          self:
                            type: string
                          integrations:
                            type: string
                          sections:
                            type: string
                          prizes:
                            type: string
                          gameDataStatistics:
                            type: string
                          bulkPrizes:
                            type: string
                        type: object
                    type: object
        '401':
          description: |
            Unauthorized.

            Possible reasons:
            Token has expired
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: 'message": "Unauthenticated.'
  '/v1/campaign/{campaign}/vouchers':
    get:
      tags:
        - campaigns
      summary: Campaign vouchers
      description: |
        List all campaign vouchers.
        This API lists all vouchers associated to the campaign.

        Requires scope:

        `campaigns.voucher.list`
      security:
        - clientCredentials:
            - campaigns.voucher.list
      parameters:
        - name: campaign
          in: path
          description: Campaign id
          required: true
          schema:
            type: integer
    

# --- truncated at 32 KB (108 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/playable/refs/heads/main/openapi/playable-api-openapi.yml