{
  "openapi": "3.1.0",
  "info": {
    "title": "QRBold API",
    "version": "v1",
    "description": "REST API for digital business cards and dynamic QR codes. Generated from the definitions behind https://qrbold.com/developers. There is one environment: every request acts on the live account the key belongs to.",
    "contact": {
      "name": "QRBold",
      "email": "hello@qrbold.com",
      "url": "https://qrbold.com/developers"
    }
  },
  "externalDocs": {
    "description": "QRBold developer documentation",
    "url": "https://qrbold.com/developers"
  },
  "servers": [
    {
      "url": "https://api.qrbold.com/api/public/v1",
      "description": "Production (the only environment)"
    }
  ],
  "tags": [
    {
      "name": "Account",
      "description": "Check that a key works and see what it is allowed to do."
    },
    {
      "name": "Digital business cards",
      "description": "Create, read, update and delete digital business cards."
    },
    {
      "name": "Card templates",
      "description": "Read the templates a card can be created from, and the field rules each one imposes."
    },
    {
      "name": "QR codes",
      "description": "Create and manage dynamic QR codes that redirect to a URL, and list every other code in the account."
    },
    {
      "name": "QR images",
      "description": "Download the QR image for a QR code or a digital business card."
    },
    {
      "name": "Analytics",
      "description": "Read scan totals, a daily timeline and, on plans that include them, country and device breakdowns."
    },
    {
      "name": "Campaign ingestion",
      "description": "Create one card per request from your own JSON shape, using a template and mapping configured once in the dashboard."
    }
  ],
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyHeader": []
    }
  ],
  "paths": {
    "/me": {
      "get": {
        "operationId": "me",
        "tags": [
          "Account"
        ],
        "summary": "Check a key",
        "description": "Returns the key’s name, its scopes, the account it belongs to and its rate limit.\n\nNo scope required.\n\nRead-only and free of side effects, so it is safe to call from a health check.",
        "responses": {
          "200": {
            "description": "The key is valid and the account’s plan includes the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "api_key_context",
                  "key": {
                    "id": "cmf3jz8n10000",
                    "name": "HR onboarding sync"
                  },
                  "scopes": [
                    {
                      "scope": "cards:read",
                      "description": "List and retrieve digital business cards"
                    },
                    {
                      "scope": "cards:write",
                      "description": "Create, update and delete digital business cards"
                    }
                  ],
                  "account": {
                    "id": "cmf2x9u4w0000",
                    "email": "you@example.com",
                    "plan": "pro"
                  },
                  "rateLimit": {
                    "requestsPerMinute": 120
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/cards": {
      "post": {
        "operationId": "cards_create",
        "tags": [
          "Digital business cards"
        ],
        "summary": "Create a card",
        "description": "Creates one digital business card and returns it, including its public URL.\n\nRequired scope: cards:write.\n\nThe template’s design is copied onto the card when it is created. Editing the template later does not change cards that already exist.\n\nCheck paused in the response before printing a QR code: a paused card exists but its URL does not open.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Unknown keys are dropped without an error on this endpoint, both at the top level and inside fields. A misspelled field name therefore creates a card without that value: compare the fields in the response with what you sent.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "fields": {
                    "type": "object",
                    "description": "The person’s data. See the card fields table. Defaults to an empty object, but a template may require some fields."
                  },
                  "name": {
                    "type": "string",
                    "description": "Label shown in the dashboard, 1 to 200 characters."
                  },
                  "templateId": {
                    "type": "string",
                    "description": "Copies this template’s design onto the card and applies its field rules."
                  },
                  "shortCode": {
                    "type": "string",
                    "description": "Custom slug for the public URL: letters, numbers and hyphens, up to 100 characters."
                  },
                  "status": {
                    "type": "string",
                    "description": "published marks the card live straight away. draft marks it as not yet released, but its URL still opens for preview, so do not treat a draft as private.",
                    "enum": [
                      "draft",
                      "published"
                    ]
                  }
                }
              },
              "example": {
                "name": "Ada Lovelace",
                "templateId": "cmf3k1p7d0002",
                "shortCode": "ada-lovelace",
                "status": "published",
                "fields": {
                  "firstName": "Ada",
                  "lastName": "Lovelace",
                  "title": "Head of Engineering",
                  "company": "Analytical Engines Ltd",
                  "photoUrl": "https://example.com/photos/ada.jpg",
                  "companyLogoUrl": "https://example.com/brand/logo.png",
                  "bio": "Builds calculating machines and the teams around them.",
                  "emails": [
                    {
                      "label": "Work",
                      "value": "ada@example.com"
                    }
                  ],
                  "phones": [
                    {
                      "label": "Mobile",
                      "value": "+44 20 7946 0958"
                    }
                  ],
                  "links": [
                    {
                      "type": "website",
                      "url": "example.com"
                    },
                    {
                      "type": "linkedin",
                      "url": "linkedin.com/in/ada-lovelace"
                    }
                  ],
                  "address": {
                    "city": "London",
                    "country": "United Kingdom"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The card object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "card",
                  "id": "cmf3k2a9x0001",
                  "name": "Ada Lovelace",
                  "shortCode": "ada-lovelace",
                  "status": "published",
                  "url": "https://qrbold.com/c/ada-lovelace",
                  "vcardUrl": "https://qrbold.com/c/ada-lovelace/vcard",
                  "templateId": "cmf3k1p7d0002",
                  "externalId": null,
                  "paused": false,
                  "fields": {
                    "firstName": "Ada",
                    "lastName": "Lovelace",
                    "title": "Head of Engineering",
                    "company": "Analytical Engines Ltd",
                    "photoUrl": "https://example.com/photos/ada.jpg",
                    "companyLogoUrl": "https://example.com/brand/logo.png",
                    "bio": "Builds calculating machines and the teams around them.",
                    "emails": [
                      {
                        "label": "Work",
                        "value": "ada@example.com"
                      }
                    ],
                    "phones": [
                      {
                        "label": "Mobile",
                        "value": "+44 20 7946 0958"
                      }
                    ],
                    "links": [
                      {
                        "type": "website",
                        "url": "example.com"
                      },
                      {
                        "type": "linkedin",
                        "url": "linkedin.com/in/ada-lovelace"
                      }
                    ],
                    "address": {
                      "city": "London",
                      "country": "United Kingdom"
                    }
                  },
                  "createdAt": "2026-10-09T09:30:00.000Z",
                  "updatedAt": "2026-10-09T09:30:00.000Z"
                }
              }
            }
          },
          "400": {
            "description": "invalid_request: The custom shortCode is already taken. | reserved_short_link: The custom shortCode is a word the platform keeps for itself.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "invalid_request",
                    "code": "invalid_request",
                    "message": "This short code / slug is already in use. Please choose another."
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API. | limit_exhausted_cards: The account has used every card its plan covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API. | resource_not_found: Nothing with that id exists in this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_key_reused: This Idempotency-Key was already used with a different request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "conflict",
                    "code": "idempotency_key_reused",
                    "message": "This Idempotency-Key was already used with a different request body. Use a new key for a new request."
                  }
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: The request body or the query string did not pass validation. | validation_failed: The card’s template does not allow what was sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "invalid_request",
                    "code": "validation_failed",
                    "message": "One or more fields are invalid.",
                    "details": [
                      {
                        "field": "fields.links.0.type",
                        "message": "Invalid enum value",
                        "code": "invalid_enum_value"
                      },
                      {
                        "field": "shortCode",
                        "message": "Slugs can only contain letters, numbers, and hyphens",
                        "code": "invalid_string"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "cards_list",
        "tags": [
          "Digital business cards"
        ],
        "summary": "List cards",
        "description": "Returns the account’s cards, newest first, one page at a time.\n\nRequired scope: cards:read.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Items per page, 1 to 100. Default: 25.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "How many items to skip. Default: 0.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Matches part of the card’s name, ignoring case. Up to 200 characters.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "templateId",
            "in": "query",
            "required": false,
            "description": "Only cards created from this template.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Only cards in this status. Archived cards are left out unless you ask for them.",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "published",
                "paused",
                "archived"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A list envelope of card objects.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "card",
                      "id": "cmf3k2a9x0001",
                      "name": "Ada Lovelace",
                      "shortCode": "ada-lovelace",
                      "status": "published",
                      "url": "https://qrbold.com/c/ada-lovelace",
                      "vcardUrl": "https://qrbold.com/c/ada-lovelace/vcard",
                      "templateId": "cmf3k1p7d0002",
                      "externalId": null,
                      "paused": false,
                      "fields": {
                        "firstName": "Ada",
                        "lastName": "Lovelace",
                        "title": "Head of Engineering",
                        "company": "Analytical Engines Ltd",
                        "photoUrl": "https://example.com/photos/ada.jpg",
                        "companyLogoUrl": "https://example.com/brand/logo.png",
                        "bio": "Builds calculating machines and the teams around them.",
                        "emails": [
                          {
                            "label": "Work",
                            "value": "ada@example.com"
                          }
                        ],
                        "phones": [
                          {
                            "label": "Mobile",
                            "value": "+44 20 7946 0958"
                          }
                        ],
                        "links": [
                          {
                            "type": "website",
                            "url": "example.com"
                          },
                          {
                            "type": "linkedin",
                            "url": "linkedin.com/in/ada-lovelace"
                          }
                        ],
                        "address": {
                          "city": "London",
                          "country": "United Kingdom"
                        }
                      },
                      "createdAt": "2026-10-09T09:30:00.000Z",
                      "updatedAt": "2026-10-09T09:30:00.000Z"
                    }
                  ],
                  "pagination": {
                    "total": 1,
                    "limit": 25,
                    "offset": 0,
                    "hasMore": false
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: The request body or the query string did not pass validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "invalid_request",
                    "code": "validation_failed",
                    "message": "One or more fields are invalid.",
                    "details": [
                      {
                        "field": "fields.links.0.type",
                        "message": "Invalid enum value",
                        "code": "invalid_enum_value"
                      },
                      {
                        "field": "shortCode",
                        "message": "Slugs can only contain letters, numbers, and hyphens",
                        "code": "invalid_string"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/cards/{id}": {
      "get": {
        "operationId": "cards_get",
        "tags": [
          "Digital business cards"
        ],
        "summary": "Retrieve a card",
        "description": "Returns one card by id.\n\nRequired scope: cards:read.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The card’s id, as returned in the card object.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The card object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "card",
                  "id": "cmf3k2a9x0001",
                  "name": "Ada Lovelace",
                  "shortCode": "ada-lovelace",
                  "status": "published",
                  "url": "https://qrbold.com/c/ada-lovelace",
                  "vcardUrl": "https://qrbold.com/c/ada-lovelace/vcard",
                  "templateId": "cmf3k1p7d0002",
                  "externalId": null,
                  "paused": false,
                  "fields": {
                    "firstName": "Ada",
                    "lastName": "Lovelace",
                    "title": "Head of Engineering",
                    "company": "Analytical Engines Ltd",
                    "photoUrl": "https://example.com/photos/ada.jpg",
                    "companyLogoUrl": "https://example.com/brand/logo.png",
                    "bio": "Builds calculating machines and the teams around them.",
                    "emails": [
                      {
                        "label": "Work",
                        "value": "ada@example.com"
                      }
                    ],
                    "phones": [
                      {
                        "label": "Mobile",
                        "value": "+44 20 7946 0958"
                      }
                    ],
                    "links": [
                      {
                        "type": "website",
                        "url": "example.com"
                      },
                      {
                        "type": "linkedin",
                        "url": "linkedin.com/in/ada-lovelace"
                      }
                    ],
                    "address": {
                      "city": "London",
                      "country": "United Kingdom"
                    }
                  },
                  "createdAt": "2026-10-09T09:30:00.000Z",
                  "updatedAt": "2026-10-09T09:30:00.000Z"
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API. | resource_not_found: Nothing with that id exists in this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "cards_update",
        "tags": [
          "Digital business cards"
        ],
        "summary": "Update a card",
        "description": "Replaces the card’s data, and optionally moves it to another template.\n\nRequired scope: cards:write.\n\nThe public URL and the QR code do not change when a card is updated, so nothing has to be reprinted.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The card’s id, as returned in the card object.",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Only fields and templateId are accepted: any other top-level key is rejected with 422. The card’s name follows the person’s name automatically. The design, status and short code cannot be changed here.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "fields": {
                    "type": "object",
                    "description": "The card’s complete data. Scalar fields you leave out are cleared; rich sections you leave out are kept, and null clears one."
                  },
                  "templateId": {
                    "type": "string",
                    "description": "Link the card to a different template’s field rules, or null to unlink it."
                  }
                },
                "required": [
                  "fields"
                ]
              },
              "example": {
                "fields": {
                  "firstName": "Ada",
                  "lastName": "Lovelace",
                  "title": "Chief Technology Officer",
                  "company": "Analytical Engines Ltd",
                  "photoUrl": "https://example.com/photos/ada.jpg",
                  "companyLogoUrl": "https://example.com/brand/logo.png",
                  "bio": "Builds calculating machines and the teams around them.",
                  "emails": [
                    {
                      "label": "Work",
                      "value": "ada@example.com"
                    }
                  ],
                  "phones": [
                    {
                      "label": "Mobile",
                      "value": "+44 20 7946 0958"
                    }
                  ],
                  "links": [
                    {
                      "type": "website",
                      "url": "example.com"
                    },
                    {
                      "type": "linkedin",
                      "url": "linkedin.com/in/ada-lovelace"
                    }
                  ],
                  "address": {
                    "city": "London",
                    "country": "United Kingdom"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated card object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "card",
                  "id": "cmf3k2a9x0001",
                  "name": "Ada Lovelace",
                  "shortCode": "ada-lovelace",
                  "status": "published",
                  "url": "https://qrbold.com/c/ada-lovelace",
                  "vcardUrl": "https://qrbold.com/c/ada-lovelace/vcard",
                  "templateId": "cmf3k1p7d0002",
                  "externalId": null,
                  "paused": false,
                  "fields": {
                    "firstName": "Ada",
                    "lastName": "Lovelace",
                    "title": "Chief Technology Officer",
                    "company": "Analytical Engines Ltd",
                    "photoUrl": "https://example.com/photos/ada.jpg",
                    "companyLogoUrl": "https://example.com/brand/logo.png",
                    "bio": "Builds calculating machines and the teams around them.",
                    "emails": [
                      {
                        "label": "Work",
                        "value": "ada@example.com"
                      }
                    ],
                    "phones": [
                      {
                        "label": "Mobile",
                        "value": "+44 20 7946 0958"
                      }
                    ],
                    "links": [
                      {
                        "type": "website",
                        "url": "example.com"
                      },
                      {
                        "type": "linkedin",
                        "url": "linkedin.com/in/ada-lovelace"
                      }
                    ],
                    "address": {
                      "city": "London",
                      "country": "United Kingdom"
                    }
                  },
                  "createdAt": "2026-10-09T09:30:00.000Z",
                  "updatedAt": "2026-10-09T10:05:00.000Z"
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API. | resource_not_found: Nothing with that id exists in this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_key_reused: This Idempotency-Key was already used with a different request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "conflict",
                    "code": "idempotency_key_reused",
                    "message": "This Idempotency-Key was already used with a different request body. Use a new key for a new request."
                  }
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: The request body or the query string did not pass validation. | validation_failed: The card’s template does not allow what was sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "invalid_request",
                    "code": "validation_failed",
                    "message": "One or more fields are invalid.",
                    "details": [
                      {
                        "field": "fields.links.0.type",
                        "message": "Invalid enum value",
                        "code": "invalid_enum_value"
                      },
                      {
                        "field": "shortCode",
                        "message": "Slugs can only contain letters, numbers, and hyphens",
                        "code": "invalid_string"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "cards_delete",
        "tags": [
          "Digital business cards"
        ],
        "summary": "Delete a card",
        "description": "Moves the card to the account’s Trash. Its public URL stops opening immediately.\n\nRequired scope: cards:write.\n\nThe card can be restored from Trash in the dashboard for the retention period. There is no restore endpoint in the REST API.\n\nAny printed QR code that points at the card leads to an “unavailable” page until it is restored.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The card’s id, as returned in the card object.",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "No body."
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API. | resource_not_found: Nothing with that id exists in this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/cards/{id}/wallet": {
      "get": {
        "operationId": "cards_wallet",
        "tags": [
          "Digital business cards"
        ],
        "summary": "Get wallet links",
        "description": "Returns the links that add the card to Apple Wallet and Google Wallet, and how many passes are installed.\n\nRequired scope: cards:read.\n\nRead-only. The pass design is edited on the card’s Wallet tab in the dashboard.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The card’s id, as returned in the card object.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A wallet_links object. A link is null when that wallet cannot issue a pass for this card.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "wallet_links",
                  "cardId": "cmf3k2a9x0001",
                  "enabled": true,
                  "apple": "https://qrbold.com/c/ada-lovelace/wallet/apple",
                  "google": "https://qrbold.com/c/ada-lovelace/wallet/google",
                  "installs": {
                    "apple": {
                      "issued": 12,
                      "installed": 9
                    },
                    "google": {
                      "issued": 4,
                      "installed": 3
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API. | resource_not_found: Nothing with that id exists in this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/templates": {
      "get": {
        "operationId": "templates_list",
        "tags": [
          "Card templates"
        ],
        "summary": "List templates",
        "description": "Returns the card templates in the account.\n\nRequired scope: templates:read.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Items per page, 1 to 100. Default: 25.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "How many items to skip. Default: 0.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A list envelope of card_template objects.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "card_template",
                      "id": "cmf3k1p7d0002",
                      "name": "Company standard",
                      "policy": {
                        "theme": "locked",
                        "blocks": "reorder_only",
                        "fields": {
                          "company": {
                            "mode": "locked",
                            "value": "Analytical Engines Ltd"
                          },
                          "firstName": {
                            "mode": "required"
                          }
                        }
                      },
                      "createdAt": "2026-09-01T08:00:00.000Z",
                      "updatedAt": "2026-09-20T14:12:00.000Z"
                    }
                  ],
                  "pagination": {
                    "total": 1,
                    "limit": 25,
                    "offset": 0,
                    "hasMore": false
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: The request body or the query string did not pass validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "invalid_request",
                    "code": "validation_failed",
                    "message": "One or more fields are invalid.",
                    "details": [
                      {
                        "field": "fields.links.0.type",
                        "message": "Invalid enum value",
                        "code": "invalid_enum_value"
                      },
                      {
                        "field": "shortCode",
                        "message": "Slugs can only contain letters, numbers, and hyphens",
                        "code": "invalid_string"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/templates/{id}": {
      "get": {
        "operationId": "templates_get",
        "tags": [
          "Card templates"
        ],
        "summary": "Retrieve a template",
        "description": "Returns one template, including the field policy it applies to its cards.\n\nRequired scope: templates:read.\n\npolicy.fields lists a mode per field: locked, prefilled, required, optional or hidden. Writing to a locked or hidden field, or leaving a required one empty, answers 422.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The template’s id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The card_template object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "card_template",
                  "id": "cmf3k1p7d0002",
                  "name": "Company standard",
                  "policy": {
                    "theme": "locked",
                    "blocks": "reorder_only",
                    "fields": {
                      "company": {
                        "mode": "locked",
                        "value": "Analytical Engines Ltd"
                      },
                      "firstName": {
                        "mode": "required"
                      }
                    }
                  },
                  "createdAt": "2026-09-01T08:00:00.000Z",
                  "updatedAt": "2026-09-20T14:12:00.000Z"
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API. | resource_not_found: Nothing with that id exists in this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/qr-codes": {
      "post": {
        "operationId": "qr_create",
        "tags": [
          "QR codes"
        ],
        "summary": "Create a QR code",
        "description": "Creates a dynamic QR code that redirects to a URL you choose.\n\nRequired scope: qr:write.\n\nStyling (colours, shapes, logo, frame) is not set through the REST API. A new code starts black on white; design it in the dashboard and the image endpoint returns that design.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Unknown keys are rejected with 422 on this endpoint.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Label shown in the dashboard, 1 to 200 characters."
                  },
                  "destinationUrl": {
                    "type": "string",
                    "description": "Where a scan lands. Must be a full http or https URL. Can be changed later."
                  },
                  "shortCode": {
                    "type": "string",
                    "description": "Custom slug: letters, numbers and hyphens, up to 100 characters."
                  },
                  "status": {
                    "type": "string",
                    "description": "draft marks the code as not yet released. Its short link still resolves for preview until it has been published and then unpublished.",
                    "enum": [
                      "draft",
                      "published"
                    ]
                  }
                },
                "required": [
                  "name",
                  "destinationUrl"
                ]
              },
              "example": {
                "name": "Spring menu",
                "destinationUrl": "https://example.com/menu/spring",
                "shortCode": "spring-menu"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The QR code object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "qr_code",
                  "id": "cmf3k4c2e0003",
                  "name": "Spring menu",
                  "type": "url",
                  "status": "published",
                  "shortCode": "spring-menu",
                  "url": "https://qrbold.com/p/spring-menu",
                  "destinationUrl": "https://example.com/menu/spring",
                  "paused": false,
                  "scanCount": 0,
                  "createdAt": "2026-10-09T09:35:00.000Z",
                  "updatedAt": "2026-10-09T09:35:00.000Z"
                }
              }
            }
          },
          "400": {
            "description": "invalid_request: The custom shortCode is already taken. | reserved_short_link: The custom shortCode is a word the platform keeps for itself.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "invalid_request",
                    "code": "invalid_request",
                    "message": "This short code / slug is already in use. Please choose another."
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API. | limit_exhausted_products: The account has reached its plan’s QR code limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_key_reused: This Idempotency-Key was already used with a different request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "conflict",
                    "code": "idempotency_key_reused",
                    "message": "This Idempotency-Key was already used with a different request body. Use a new key for a new request."
                  }
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: The request body or the query string did not pass validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "invalid_request",
                    "code": "validation_failed",
                    "message": "One or more fields are invalid.",
                    "details": [
                      {
                        "field": "fields.links.0.type",
                        "message": "Invalid enum value",
                        "code": "invalid_enum_value"
                      },
                      {
                        "field": "shortCode",
                        "message": "Slugs can only contain letters, numbers, and hyphens",
                        "code": "invalid_string"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "qr_list",
        "tags": [
          "QR codes"
        ],
        "summary": "List QR codes",
        "description": "Returns every QR code in the account that is not a digital business card, newest first.\n\nRequired scope: qr:read.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Items per page, 1 to 100. Default: 25.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "How many items to skip. Default: 0.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Matches part of the name, the slug or the destination URL, ignoring case.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Only codes in this status. Archived codes are left out unless you ask for them.",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "published",
                "paused",
                "archived"
              ]
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Only codes of this type.",
            "schema": {
              "type": "string",
              "enum": [
                "url",
                "file",
                "page",
                "gs1"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A list envelope of qr_code objects.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "qr_code",
                      "id": "cmf3k4c2e0003",
                      "name": "Spring menu",
                      "type": "url",
                      "status": "published",
                      "shortCode": "spring-menu",
                      "url": "https://qrbold.com/p/spring-menu",
                      "destinationUrl": "https://example.com/menu/spring",
                      "paused": false,
                      "scanCount": 0,
                      "createdAt": "2026-10-09T09:35:00.000Z",
                      "updatedAt": "2026-10-09T09:35:00.000Z"
                    }
                  ],
                  "pagination": {
                    "total": 1,
                    "limit": 25,
                    "offset": 0,
                    "hasMore": false
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: The request body or the query string did not pass validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "invalid_request",
                    "code": "validation_failed",
                    "message": "One or more fields are invalid.",
                    "details": [
                      {
                        "field": "fields.links.0.type",
                        "message": "Invalid enum value",
                        "code": "invalid_enum_value"
                      },
                      {
                        "field": "shortCode",
                        "message": "Slugs can only contain letters, numbers, and hyphens",
                        "code": "invalid_string"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/qr-codes/{id}": {
      "get": {
        "operationId": "qr_get",
        "tags": [
          "QR codes"
        ],
        "summary": "Retrieve a QR code",
        "description": "Returns one QR code by id.\n\nRequired scope: qr:read.\n\nA card id answers 404 here. Cards are read through /cards.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The QR code’s id, as returned in the QR code object.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The QR code object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "qr_code",
                  "id": "cmf3k4c2e0003",
                  "name": "Spring menu",
                  "type": "url",
                  "status": "published",
                  "shortCode": "spring-menu",
                  "url": "https://qrbold.com/p/spring-menu",
                  "destinationUrl": "https://example.com/menu/spring",
                  "paused": false,
                  "scanCount": 42,
                  "createdAt": "2026-10-09T09:35:00.000Z",
                  "updatedAt": "2026-10-09T09:35:00.000Z"
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API. | resource_not_found: Nothing with that id exists in this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "qr_update",
        "tags": [
          "QR codes"
        ],
        "summary": "Update a QR code",
        "description": "Renames a code, points it at a new destination, or changes its status.\n\nRequired scope: qr:write.\n\nChanging destinationUrl does not change the printed code. That is what makes it dynamic.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The QR code’s id, as returned in the QR code object.",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Send at least one field. Fields you leave out are not changed. Unknown keys are rejected with 422.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "1 to 200 characters."
                  },
                  "destinationUrl": {
                    "type": "string",
                    "description": "A full http or https URL. URL codes only; other types answer 422."
                  },
                  "status": {
                    "type": "string",
                    "description": "paused stops the code redirecting without losing it. archived hides it from the default list. Both are undone by setting published.",
                    "enum": [
                      "draft",
                      "published",
                      "paused",
                      "archived"
                    ]
                  }
                }
              },
              "example": {
                "destinationUrl": "https://example.com/menu/summer"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated QR code object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "qr_code",
                  "id": "cmf3k4c2e0003",
                  "name": "Spring menu",
                  "type": "url",
                  "status": "published",
                  "shortCode": "spring-menu",
                  "url": "https://qrbold.com/p/spring-menu",
                  "destinationUrl": "https://example.com/menu/summer",
                  "paused": false,
                  "scanCount": 42,
                  "createdAt": "2026-10-09T09:35:00.000Z",
                  "updatedAt": "2026-10-09T10:20:00.000Z"
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API. | resource_not_found: Nothing with that id exists in this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_key_reused: This Idempotency-Key was already used with a different request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "conflict",
                    "code": "idempotency_key_reused",
                    "message": "This Idempotency-Key was already used with a different request body. Use a new key for a new request."
                  }
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: The request body or the query string did not pass validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "invalid_request",
                    "code": "validation_failed",
                    "message": "One or more fields are invalid.",
                    "details": [
                      {
                        "field": "fields.links.0.type",
                        "message": "Invalid enum value",
                        "code": "invalid_enum_value"
                      },
                      {
                        "field": "shortCode",
                        "message": "Slugs can only contain letters, numbers, and hyphens",
                        "code": "invalid_string"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "qr_delete",
        "tags": [
          "QR codes"
        ],
        "summary": "Delete a QR code",
        "description": "Moves the code to the account’s Trash. It stops redirecting immediately.\n\nRequired scope: qr:write.\n\nRestorable from Trash in the dashboard. Works for any non-card code, including ones made in the dashboard.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The QR code’s id, as returned in the QR code object.",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "No body."
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API. | resource_not_found: Nothing with that id exists in this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/qr-codes/{id}/image": {
      "get": {
        "operationId": "image_get",
        "tags": [
          "QR images"
        ],
        "summary": "Download a QR image",
        "description": "Returns the rendered QR image for a QR code or a digital business card.\n\nRequired scope: qr:read or cards:read.\n\nThe image encodes exactly the url reported by the card or QR code object, drawn with the design saved in the dashboard.\n\nThis link needs your API key, so it cannot be used as an image address in a web page or an email. Download the file and host it, or generate the image yourself from url.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "A QR code id or a card id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "File format. svg and pdf stay sharp at any print size. Default: png.",
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "svg",
                "pdf",
                "jpeg",
                "webp"
              ]
            }
          },
          {
            "name": "size",
            "in": "query",
            "required": false,
            "description": "Width in pixels, 128 to 4096. A framed code is taller than it is wide. pdf is one page at 300 dpi. Default: 512.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "transparent",
            "in": "query",
            "required": false,
            "description": "true leaves the background clear. png, webp and svg only. Default: false.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "description": "true answers with Content-Disposition: attachment so a browser saves the file. Default: false.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The image bytes, with a matching Content-Type and a suggested filename. Cached privately for an hour.",
            "content": {
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/svg+xml": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/webp": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API. | resource_not_found: Nothing with that id exists in this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: The request body or the query string did not pass validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "invalid_request",
                    "code": "validation_failed",
                    "message": "One or more fields are invalid.",
                    "details": [
                      {
                        "field": "fields.links.0.type",
                        "message": "Invalid enum value",
                        "code": "invalid_enum_value"
                      },
                      {
                        "field": "shortCode",
                        "message": "Slugs can only contain letters, numbers, and hyphens",
                        "code": "invalid_string"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/analytics/overview": {
      "get": {
        "operationId": "analytics_overview",
        "tags": [
          "Analytics"
        ],
        "summary": "Account scan statistics",
        "description": "Returns scan statistics for the whole account, with the five busiest codes in the period.\n\nRequired scope: analytics:read.",
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "required": false,
            "description": "The period to report. Default: 30d.",
            "schema": {
              "type": "string",
              "enum": [
                "7d",
                "30d",
                "90d",
                "12m"
              ]
            }
          },
          {
            "name": "timeZone",
            "in": "query",
            "required": false,
            "description": "IANA time zone the daily buckets are cut in, e.g. Europe/London. Default: UTC.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A scan_stats object with qrCodeId null and topQrCodes present.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "scan_stats",
                  "qrCodeId": null,
                  "range": "30d",
                  "period": {
                    "start": "2026-09-09T00:00:00.000Z",
                    "end": "2026-10-09T09:40:00.000Z",
                    "days": 30
                  },
                  "clamped": false,
                  "historyDays": -1,
                  "totalScans": 120,
                  "uniqueVisitors": 80,
                  "previousPeriodScans": 100,
                  "trend": "+20%",
                  "timeline": [
                    {
                      "date": "2026-10-07",
                      "scans": 6
                    },
                    {
                      "date": "2026-10-08",
                      "scans": 9
                    }
                  ],
                  "topCountries": [
                    {
                      "country": "United Kingdom",
                      "code": "GB",
                      "scans": 74
                    }
                  ],
                  "devices": [
                    {
                      "device": "Mobile",
                      "scans": 108,
                      "percent": 90
                    }
                  ],
                  "topQrCodes": [
                    {
                      "id": "cmf3k2a9x0001",
                      "name": "Ada Lovelace",
                      "type": "card",
                      "scans": 74
                    },
                    {
                      "id": "cmf3k4c2e0003",
                      "name": "Spring menu",
                      "type": "url",
                      "scans": 46
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: The request body or the query string did not pass validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "invalid_request",
                    "code": "validation_failed",
                    "message": "One or more fields are invalid.",
                    "details": [
                      {
                        "field": "fields.links.0.type",
                        "message": "Invalid enum value",
                        "code": "invalid_enum_value"
                      },
                      {
                        "field": "shortCode",
                        "message": "Slugs can only contain letters, numbers, and hyphens",
                        "code": "invalid_string"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/analytics/{id}": {
      "get": {
        "operationId": "analytics_one",
        "tags": [
          "Analytics"
        ],
        "summary": "Scan statistics for one code or card",
        "description": "Returns scan statistics for a single QR code or digital business card.\n\nRequired scope: analytics:read.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "A QR code id or a card id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "range",
            "in": "query",
            "required": false,
            "description": "The period to report. Default: 30d.",
            "schema": {
              "type": "string",
              "enum": [
                "7d",
                "30d",
                "90d",
                "12m"
              ]
            }
          },
          {
            "name": "timeZone",
            "in": "query",
            "required": false,
            "description": "IANA time zone the daily buckets are cut in. Default: UTC.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A scan_stats object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "scan_stats",
                  "qrCodeId": "cmf3k2a9x0001",
                  "range": "30d",
                  "period": {
                    "start": "2026-09-09T00:00:00.000Z",
                    "end": "2026-10-09T09:40:00.000Z",
                    "days": 30
                  },
                  "clamped": false,
                  "historyDays": -1,
                  "totalScans": 120,
                  "uniqueVisitors": 80,
                  "previousPeriodScans": 100,
                  "trend": "+20%",
                  "timeline": [
                    {
                      "date": "2026-10-07",
                      "scans": 6
                    },
                    {
                      "date": "2026-10-08",
                      "scans": 9
                    }
                  ],
                  "topCountries": [
                    {
                      "country": "United Kingdom",
                      "code": "GB",
                      "scans": 74
                    }
                  ],
                  "devices": [
                    {
                      "device": "Mobile",
                      "scans": 108,
                      "percent": 90
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API. | resource_not_found: Nothing with that id exists in this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "422": {
            "description": "validation_failed: The request body or the query string did not pass validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "invalid_request",
                    "code": "validation_failed",
                    "message": "One or more fields are invalid.",
                    "details": [
                      {
                        "field": "fields.links.0.type",
                        "message": "Invalid enum value",
                        "code": "invalid_enum_value"
                      },
                      {
                        "field": "shortCode",
                        "message": "Slugs can only contain letters, numbers, and hyphens",
                        "code": "invalid_string"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/campaigns": {
      "get": {
        "operationId": "campaigns_list",
        "tags": [
          "Campaign ingestion"
        ],
        "summary": "List campaigns",
        "description": "Returns the account’s digital business card campaigns.\n\nRequired scope: cards:read.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Items per page, 1 to 100. Default: 20.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "How many items to skip. Default: 0.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A list envelope of campaign objects. A campaign-scoped key sees only its own campaign.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "campaign",
                      "id": "cmf3k0b5q0004",
                      "name": "New starters 2026",
                      "status": "active",
                      "apiEnabled": true,
                      "templateId": "cmf3k1p7d0002",
                      "createdAt": "2026-09-15T11:00:00.000Z"
                    }
                  ],
                  "pagination": {
                    "total": 1,
                    "limit": 20,
                    "offset": 0,
                    "hasMore": false
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/campaigns/{campaignId}": {
      "get": {
        "operationId": "campaigns_get",
        "tags": [
          "Campaign ingestion"
        ],
        "summary": "Retrieve a campaign",
        "description": "Returns one campaign, including whether its API is switched on.\n\nRequired scope: cards:read.",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign’s id. Shown on the campaign’s API tab in the dashboard and returned by GET /campaigns.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The campaign object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "campaign",
                  "id": "cmf3k0b5q0004",
                  "name": "New starters 2026",
                  "status": "active",
                  "apiEnabled": true,
                  "templateId": "cmf3k1p7d0002",
                  "createdAt": "2026-09-15T11:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API. | key_scoped_to_campaign: A campaign-scoped key was used somewhere it is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API. | resource_not_found: Nothing with that id exists in this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/campaigns/{campaignId}/schema": {
      "get": {
        "operationId": "campaigns_schema",
        "tags": [
          "Campaign ingestion"
        ],
        "summary": "Get a campaign’s payload schema",
        "description": "Returns the JSON shape this campaign accepts, derived from its template, with a ready-to-post sample.\n\nRequired scope: cards:read.\n\nstale: true means the template changed after the configuration was activated. Requests still work; re-read the schema.",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign’s id. Shown on the campaign’s API tab in the dashboard and returned by GET /campaigns.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A campaign_schema object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "campaign_schema",
                  "campaignId": "cmf3k0b5q0004",
                  "payloadMode": "native",
                  "templateId": "cmf3k1p7d0002",
                  "fingerprint": "9f3a1c22",
                  "activatedFingerprint": "9f3a1c22",
                  "stale": false,
                  "fields": [
                    {
                      "key": "firstName",
                      "label": "First name",
                      "required": true
                    }
                  ],
                  "sections": [
                    {
                      "key": "gallery",
                      "label": "Gallery",
                      "kind": "list",
                      "max": 24,
                      "props": [
                        {
                          "prop": "url",
                          "label": "Photo"
                        }
                      ]
                    }
                  ],
                  "blocks": [
                    {
                      "id": "heading-1",
                      "type": "heading",
                      "props": [
                        {
                          "prop": "text",
                          "value": "Welcome"
                        }
                      ]
                    }
                  ],
                  "sample": {
                    "externalId": "EMP-1001",
                    "firstName": "Ada",
                    "lastName": "Lovelace",
                    "gallery": []
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API. | key_scoped_to_campaign: A campaign-scoped key was used somewhere it is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API. | resource_not_found: Nothing with that id exists in this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/campaigns/{campaignId}/cards/test": {
      "post": {
        "operationId": "campaigns_test",
        "tags": [
          "Campaign ingestion"
        ],
        "summary": "Dry-run a campaign card",
        "description": "Runs a payload through the campaign exactly as the real endpoint would, and creates nothing.\n\nRequired scope: cards:write.",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign’s id. Shown on the campaign’s API tab in the dashboard and returned by GET /campaigns.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The same body you would send to the real endpoint: your own JSON in mapped mode, a card document in native mode.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              },
              "example": {
                "employee": {
                  "id": "EMP-1001",
                  "name": {
                    "first": "Ada",
                    "last": "Lovelace"
                  },
                  "contact": {
                    "email": "ada@example.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A dry_run object. The status is 200 whether or not the payload would be accepted; read ok.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "dry_run",
                  "ok": true,
                  "externalId": "EMP-1001",
                  "resolvedFields": {
                    "firstName": "Ada",
                    "lastName": "Lovelace",
                    "emails.0.value": "ada@example.com"
                  },
                  "unmappedPaths": [],
                  "shortCode": null,
                  "warnings": [],
                  "errors": []
                }
              }
            }
          },
          "400": {
            "description": "invalid_json_structure: The body is valid JSON but not an object.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "invalid_request",
                    "code": "invalid_json_structure",
                    "message": "The request body must be a JSON object. One request creates one card."
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API. | campaign_api_disabled: The campaign is not accepting API requests. | key_scoped_to_campaign: A campaign-scoped key was used somewhere it is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API. | resource_not_found: Nothing with that id exists in this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "409": {
            "description": "api_not_configured: The campaign has never had an API configuration activated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "conflict",
                    "code": "api_not_configured",
                    "message": "This campaign has no active API configuration. Configure it in the dashboard first."
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/campaigns/{campaignId}/cards": {
      "post": {
        "operationId": "campaigns_create",
        "tags": [
          "Campaign ingestion"
        ],
        "summary": "Create a card in a campaign",
        "description": "Creates one card from a single record, using the campaign’s template, mapping and short-link rule.\n\nRequired scope: cards:write.\n\nYour identifier is unique inside the campaign, so a repeated export cannot create a second card for the same person.",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign’s id. Shown on the campaign’s API tab in the dashboard and returned by GET /campaigns.",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "One JSON object, up to 1 MB, creates one card. In mapped mode it is your own record, unchanged. In native mode it is a card document whose top-level externalId is required. Do not send templateId: the campaign owns it.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              },
              "example": {
                "employee": {
                  "id": "EMP-1001",
                  "name": {
                    "first": "Ada",
                    "last": "Lovelace"
                  },
                  "contact": {
                    "email": "ada@example.com",
                    "mobile": "+44 20 7946 0958"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The card object, with externalId set to your identifier. The response carries a Request-Id header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "object": "card",
                  "id": "cmf3k2a9x0001",
                  "name": "Ada Lovelace",
                  "shortCode": "k3Vq8ZtB",
                  "status": "published",
                  "url": "https://qrbold.com/c/k3Vq8ZtB",
                  "vcardUrl": "https://qrbold.com/c/k3Vq8ZtB/vcard",
                  "templateId": "cmf3k1p7d0002",
                  "externalId": "EMP-1001",
                  "paused": false,
                  "fields": {
                    "firstName": "Ada",
                    "lastName": "Lovelace",
                    "title": "Head of Engineering",
                    "company": "Analytical Engines Ltd",
                    "photoUrl": "https://example.com/photos/ada.jpg",
                    "companyLogoUrl": "https://example.com/brand/logo.png",
                    "bio": "Builds calculating machines and the teams around them.",
                    "emails": [
                      {
                        "label": "Work",
                        "value": "ada@example.com"
                      }
                    ],
                    "phones": [
                      {
                        "label": "Mobile",
                        "value": "+44 20 7946 0958"
                      }
                    ],
                    "links": [
                      {
                        "type": "website",
                        "url": "example.com"
                      },
                      {
                        "type": "linkedin",
                        "url": "linkedin.com/in/ada-lovelace"
                      }
                    ],
                    "address": {
                      "city": "London",
                      "country": "United Kingdom"
                    }
                  },
                  "createdAt": "2026-10-09T09:30:00.000Z",
                  "updatedAt": "2026-10-09T09:30:00.000Z"
                }
              }
            }
          },
          "400": {
            "description": "invalid_json: The request body is not valid JSON. | invalid_json_structure: The body is valid JSON but not an object. | payload_too_large: The request body is over the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "invalid_request",
                    "code": "invalid_json",
                    "message": "The request body is not valid JSON."
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key: The request did not carry a key the API accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "authentication_error",
                    "code": "invalid_api_key",
                    "message": "Invalid API key"
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The key is valid but does not hold the scope this endpoint needs. | upgrade_required_api: The account’s plan does not include the REST API. | campaign_api_disabled: The campaign is not accepting API requests. | limit_exhausted_cards: The account has used every card its plan covers. | key_scoped_to_campaign: A campaign-scoped key was used somewhere it is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "permission_error",
                    "code": "forbidden",
                    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_endpoint: The path or method is not part of the API. | resource_not_found: Nothing with that id exists in this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found",
                    "code": "unknown_endpoint",
                    "message": "No such endpoint: PUT /api/public/v1/cards/cmf3k2a9x0001"
                  }
                }
              }
            }
          },
          "409": {
            "description": "duplicate_external_id: A card with that identifier already exists in the campaign. | duplicate_in_trash: A card with that identifier is sitting in the account’s Trash. | short_link_already_exists: The custom short link the campaign resolved from the payload is taken. | api_not_configured: The campaign has never had an API configuration activated. | idempotency_key_reused: This Idempotency-Key was already used with a different request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "conflict",
                    "code": "duplicate_external_id",
                    "message": "A card with external id \"EMP-1001\" already exists in this campaign."
                  }
                }
              }
            }
          },
          "422": {
            "description": "missing_external_id: The payload did not carry your identifier for the person. | invalid_external_id: The identifier is not usable. | invalid_short_link: The custom short link in a campaign payload is not valid. | invalid_payload: A native-mode campaign payload does not match the template’s schema. | validation_failed: The card’s template does not allow what was sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "invalid_request",
                    "code": "missing_external_id",
                    "message": "No value at \"employee.id\". Every request must carry your own identifier for the person."
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate limit exceeded: The key has used its requests for this minute.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "message": "API rate limit exceeded. Retry after the window resets — see the RateLimit-Reset header."
                }
              }
            }
          },
          "500": {
            "description": "internal_error: Something failed on QRBold’s side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "api_error",
                    "code": "internal_error",
                    "message": "Something went wrong on our end."
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer YOUR_API_KEY"
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Alternative to the Authorization header."
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Any unique value up to 255 characters. Repeating the request with the same key within 24 hours returns the original response.",
        "schema": {
          "type": "string",
          "maxLength": 255
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "type",
              "code",
              "message"
            ],
            "properties": {
              "type": {
                "type": "string"
              },
              "code": {
                "type": "string",
                "description": "Stable identifier. Branch on this."
              },
              "message": {
                "type": "string",
                "description": "For people. The wording can change."
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  }
}