Bubble Data API

REST API exposing the Bubble app database. Supports search with constraints, cursor-based pagination, single-record CRUD, bulk create (up to 1,000 records), and metadata discovery. Authentication uses bearer tokens (admin tokens bypass privacy rules; user tokens enforce them). Endpoints are available on both live and `version-test` (development) environments.

Documentation

Specifications

Schemas & Data

Other Resources

OpenAPI Specification

bubble-data-api-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Bubble Action Data API
  description: 'The Bubble Data API exposes the database of a Bubble app as a REST interface.

    External systems can read, search, create, modify, replace, and delete records

    of any data type defined in a Bubble app, with optional pagination, sorting,

    and search constraints. Authentication uses bearer tokens (admin API tokens

    bypass privacy rules; user tokens enforce them). Endpoints exist for live and

    development (`version-test`) environments.

    '
  version: '1.1'
  contact:
    name: Bubble Support
    url: https://bubble.io/contact
  license:
    name: Bubble Terms of Service
    url: https://bubble.io/legal/terms-of-service
servers:
- url: https://{appname}.bubbleapps.io/api/1.1
  description: Live App on Bubble subdomain
  variables:
    appname:
      default: myapp
      description: Bubble app name
- url: https://{appname}.bubbleapps.io/version-test/api/1.1
  description: Development (version-test) on Bubble subdomain
  variables:
    appname:
      default: myapp
      description: Bubble app name
- url: https://{customDomain}/api/1.1
  description: Live App on a custom domain
  variables:
    customDomain:
      default: example.com
      description: Custom domain pointing to the Bubble app
security:
- BearerAuth: []
tags:
- name: Data
  description: Read, search, create, modify, replace, and delete data things.
paths:
  /obj/{typename}:
    parameters:
    - $ref: '#/components/parameters/Typename'
    get:
      tags:
      - Data
      summary: Search Things
      description: 'Returns a list of records of the given data type. Supports search constraints,

        cursor-based pagination, sorting, and field projection.

        '
      operationId: searchThings
      parameters:
      - name: constraints
        in: query
        description: 'JSON-encoded array of search constraints. Each constraint is an object

          with `key`, `constraint_type`, and `value`. Supported constraint types:

          equals, not equal, is_empty, is_not_empty, text contains,

          not text contains, greater than, less than, in, not in, contains,

          not contains, geographic_search.

          '
        schema:
          type: string
        example: '[{"key":"unitname","constraint_type":"equals","value":"Studio 5"}]'
      - name: cursor
        in: query
        description: Zero-based start position for the page.
        schema:
          type: integer
          minimum: 0
      - name: limit
        in: query
        description: Maximum results per request (default and max 100 per page).
        schema:
          type: integer
          minimum: 1
          maximum: 100
      - name: sort_field
        in: query
        description: Field name to sort the results by.
        schema:
          type: string
      - name: descending
        in: query
        description: Sort direction. `true` for descending, `false` for ascending.
        schema:
          type: boolean
      - name: additional_sort_fields
        in: query
        description: JSON-encoded array of additional sort fields and directions.
        schema:
          type: string
      - name: exclude_remaining
        in: query
        description: Skip total-record counting for performance.
        schema:
          type: boolean
      responses:
        '200':
          description: Search response with paginated results.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
    post:
      tags:
      - Data
      summary: Create Thing
      description: Create a single new record of the given data type.
      operationId: createThing
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Thing'
      responses:
        '201':
          description: Created. Returns the unique id assigned.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /obj/{typename}/bulk:
    parameters:
    - $ref: '#/components/parameters/Typename'
    post:
      tags:
      - Data
      summary: Bulk Create Things
      description: 'Create up to 1,000 new records in a single request. The request body

        is one JSON object per line (newline-delimited JSON).

        '
      operationId: bulkCreateThings
      requestBody:
        required: true
        content:
          text/plain:
            schema:
              type: string
              description: Newline-delimited JSON, one object per line, max 1,000 lines.
      responses:
        '200':
          description: Newline-delimited JSON results, one per submitted object.
          content:
            text/plain:
              schema:
                type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /obj/{typename}/{uid}:
    parameters:
    - $ref: '#/components/parameters/Typename'
    - $ref: '#/components/parameters/Uid'
    get:
      tags:
      - Data
      summary: Get Thing
      description: Retrieve a single record by its unique id.
      operationId: getThing
      responses:
        '200':
          description: The requested record.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ThingResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
    patch:
      tags:
      - Data
      summary: Modify Thing
      description: Partially update a record. Only the provided fields are changed.
      operationId: modifyThing
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Thing'
      responses:
        '204':
          description: No Content. Modification successful.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
    put:
      tags:
      - Data
      summary: Replace Thing
      description: Fully replace the record with the supplied object.
      operationId: replaceThing
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Thing'
      responses:
        '204':
          description: No Content. Replacement successful.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
    delete:
      tags:
      - Data
      summary: Delete Thing
      description: Permanently delete a record.
      operationId: deleteThing
      responses:
        '204':
          description: No Content. Deletion successful.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
  /meta:
    get:
      tags:
      - Data
      summary: Get Data Type Metadata
      description: 'Returns the data types and their fields exposed via the Data API for the

        current environment. Useful for client code generation and discovery.

        '
      operationId: getMetadata
      responses:
        '200':
          description: Metadata response listing exposed types and fields.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        '401':
          $ref: '#/components/responses/Unauthorized'
components:
  parameters:
    Typename:
      name: typename
      in: path
      required: true
      description: Data type name in lowercase with spaces removed.
      schema:
        type: string
      example: shopping_cart
    Uid:
      name: uid
      in: path
      required: true
      description: Unique id of the record.
      schema:
        type: string
      example: 1503408875694x944431186090727200
  responses:
    Unauthorized:
      description: Missing or invalid bearer token, or token lacks required privileges.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: The requested record does not exist or the type is not exposed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    BadRequest:
      description: Invalid request payload, missing fields, or malformed constraints.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: Too many requests. The plan-level requests-per-minute limit has been exceeded.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    SearchResponse:
      type: object
      properties:
        response:
          type: object
          properties:
            cursor:
              type: integer
              description: Position of the first returned item.
            results:
              type: array
              items:
                $ref: '#/components/schemas/Thing'
            remaining:
              type: integer
              description: Records remaining beyond the returned page.
            count:
              type: integer
              description: Number of records on this page.
    Error:
      type: object
      properties:
        statusCode:
          type: integer
        body:
          type: object
          properties:
            status:
              type: string
            message:
              type: string
    Thing:
      type: object
      description: A single record. Field names match the data type's fields in the Bubble app.
      additionalProperties: true
    ThingResponse:
      type: object
      properties:
        response:
          $ref: '#/components/schemas/Thing'
    CreateResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        id:
          type: string
          description: Unique id assigned to the new record.
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Token
      description: 'Send the API token in the `Authorization` header as `Bearer <token>`.

        Admin tokens bypass privacy rules; user tokens (returned by the

        `Log the User in` workflow action) enforce privacy rules per user.

        '