{
  "openapi": "3.0.0",
  "info": {
    "title": "Shakewell Wallet",
    "description": "Public REST API for Shakewell Wallet: issue and update Apple Wallet and Google Wallet passes, manage card templates and send push notifications. Generated from the API annotations; error bodies and the create-pass request were corrected against the code. Docs: https://shakewellwallet.com/docs",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.shakewellwallet.com",
      "description": "Production"
    }
  ],
  "paths": {
    "/api/public/v1/notifications/wallet-passes/{passId}": {
      "post": {
        "tags": ["Public API - Notifications"],
        "summary": "Send notification to a wallet pass",
        "description": "Send a push notification to a specific wallet pass. The notification will be delivered to the user's device if the pass is installed.",
        "operationId": "43787cde47515092bc983335f7e21d5c",
        "parameters": [
          {
            "name": "passId",
            "in": "path",
            "description": "Unique identifier of the wallet pass. Accepts either the PassKit ID (alphanumeric string, e.g., '72Fs3a9OH1Qqrmapw7aGC9') or the database ID (integer, e.g., '248'). The PassKit ID is returned when creating a pass.",
            "required": true,
            "schema": {
              "type": "string",
              "example": "72Fs3a9OH1Qqrmapw7aGC9"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "required": ["message"],
                "properties": {
                  "message": {
                    "description": "The notification message to send to the pass holder",
                    "type": "string",
                    "maxLength": 1000,
                    "example": "Your loyalty points have been updated! You now have 50 points."
                  }
                },
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Notification sent successfully",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Notification sent successfully"
                    },
                    "data": {
                      "properties": {
                        "pass_id": {
                          "type": "string",
                          "example": "72Fs3a9OH1Qqrmapw7aGC9"
                        },
                        "status": {
                          "type": "string",
                          "example": "sent"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Wallet pass not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "WALLET_PASS_NOT_FOUND"
                    },
                    "message": {
                      "type": "string",
                      "example": "Wallet pass not found."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "VALIDATION_ERROR"
                    },
                    "message": {
                      "type": "string",
                      "example": "The given data was invalid."
                    },
                    "errors": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "NOTIFICATION_SEND_FAILED"
                    },
                    "message": {
                      "type": "string",
                      "example": "Server error."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/api/public/v1/notifications/bulk": {
      "post": {
        "tags": ["Public API - Notifications"],
        "summary": "Send bulk notifications",
        "description": "Send push notifications to multiple wallet passes at once. You can target specific passes by their IDs or all passes using a specific template.",
        "operationId": "bc1255fc62d2870d18ec0266f73db9fe",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["message"],
                "properties": {
                  "message": {
                    "type": "string",
                    "maxLength": 1000
                  },
                  "pass_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Required unless template_id is sent."
                  },
                  "template_id": {
                    "type": "integer",
                    "description": "Required unless pass_ids is sent. Sends to every pass on the template as a queued job."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bulk notification completed",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Bulk notification completed"
                    },
                    "data": {
                      "properties": {
                        "successful": {
                          "description": "List of successfully sent notifications",
                          "type": "array",
                          "items": {
                            "properties": {
                              "pass_id": {
                                "type": "string",
                                "example": "72Fs3a9OH1Qqrmapw7aGC9"
                              },
                              "status": {
                                "type": "string",
                                "example": "success"
                              }
                            },
                            "type": "object"
                          }
                        },
                        "failed": {
                          "description": "List of failed notifications",
                          "type": "array",
                          "items": {
                            "properties": {
                              "pass_id": {
                                "type": "string",
                                "example": "invalid_pass_id"
                              },
                              "status": {
                                "type": "string",
                                "example": "failed"
                              },
                              "error": {
                                "type": "string",
                                "example": "Pass not found"
                              }
                            },
                            "type": "object"
                          }
                        },
                        "summary": {
                          "properties": {
                            "total": {
                              "type": "integer",
                              "example": 10
                            },
                            "successful": {
                              "type": "integer",
                              "example": 9
                            },
                            "failed": {
                              "type": "integer",
                              "example": 1
                            }
                          },
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key."
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "VALIDATION_ERROR"
                    },
                    "message": {
                      "type": "string",
                      "example": "The given data was invalid."
                    },
                    "errors": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "BULK_NOTIFICATION_SEND_FAILED"
                    },
                    "message": {
                      "type": "string",
                      "example": "Server error."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/api/public/v1/wallet-passes": {
      "get": {
        "tags": ["Public API - Wallet Passes"],
        "summary": "List wallet passes",
        "description": "Retrieve a paginated list of wallet passes with optional filtering and sorting",
        "operationId": "2ef60be52e62e2a7f2ba9afcc13bb461",
        "parameters": [
          {
            "name": "per_page",
            "in": "query",
            "description": "Number of items per page",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 10,
              "example": 10
            }
          },
          {
            "name": "current_page",
            "in": "query",
            "description": "Current page number",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "example": 1
            }
          },
          {
            "name": "template_id",
            "in": "query",
            "description": "Filter by template ID",
            "required": false,
            "schema": {
              "type": "integer",
              "example": 38
            }
          },
          {
            "name": "query",
            "in": "query",
            "description": "Search query string",
            "required": false,
            "schema": {
              "type": "string",
              "example": "john"
            }
          },
          {
            "name": "sort_by",
            "in": "query",
            "description": "Field to sort by",
            "required": false,
            "schema": {
              "type": "string",
              "default": "created_at",
              "enum": ["created_at", "updated_at", "issued_at", "status"]
            }
          },
          {
            "name": "sort_order",
            "in": "query",
            "description": "Sort order",
            "required": false,
            "schema": {
              "type": "string",
              "default": "desc",
              "enum": ["asc", "desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Wallet passes retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Wallet passes retrieved successfully"
                    },
                    "data": {
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "properties": {
                              "id": {
                                "type": "integer",
                                "example": 248
                              },
                              "pass_id": {
                                "type": "string",
                                "example": "72Fs3a9OH1Qqrmapw7aGC9"
                              },
                              "template_id": {
                                "type": "integer",
                                "example": 38
                              },
                              "status": {
                                "type": "string",
                                "example": "active"
                              },
                              "is_installed": {
                                "type": "boolean",
                                "example": true
                              },
                              "created_at": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updated_at": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "type": "object"
                          }
                        },
                        "meta": {
                          "properties": {
                            "current_page": {
                              "type": "integer",
                              "example": 1
                            },
                            "per_page": {
                              "type": "integer",
                              "example": 10
                            },
                            "total": {
                              "type": "integer",
                              "example": 50
                            },
                            "last_page": {
                              "type": "integer",
                              "example": 5
                            }
                          },
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "WALLET_PASS_LIST_FAILED"
                    },
                    "message": {
                      "type": "string",
                      "example": "Server error."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      },
      "post": {
        "tags": ["Public API - Wallet Passes"],
        "summary": "Create a new wallet pass",
        "description": "Create a new wallet pass from a template with the provided data",
        "operationId": "68d3a4534951027b7ed4336df9240c85",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "required": ["template_id", "person"],
                "properties": {
                  "template_id": {
                    "type": "integer",
                    "example": 38,
                    "description": "A template on your account."
                  },
                  "person": {
                    "type": "object",
                    "description": "Which fields are mandatory depends on the template.",
                    "properties": {
                      "forename": {
                        "type": "string"
                      },
                      "surname": {
                        "type": "string"
                      },
                      "emailAddress": {
                        "type": "string"
                      },
                      "mobileNumber": {
                        "type": "string"
                      },
                      "dateOfBirth": {
                        "type": "string"
                      },
                      "displayName": {
                        "type": "string"
                      },
                      "salutation": {
                        "type": "string"
                      }
                    }
                  },
                  "meta": {
                    "type": "object",
                    "description": "Template field values."
                  },
                  "universal": {
                    "type": "object",
                    "description": "Extras such as a gift card expiry."
                  },
                  "barcode_value": {
                    "type": "string",
                    "maxLength": 64,
                    "description": "Printable ASCII, unique on the account. Generated if omitted."
                  }
                },
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Wallet pass created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Wallet pass created successfully"
                    },
                    "data": {
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 248
                        },
                        "pass_id": {
                          "type": "string",
                          "example": "72Fs3a9OH1Qqrmapw7aGC9"
                        },
                        "template_id": {
                          "type": "integer",
                          "example": 38
                        },
                        "status": {
                          "type": "string",
                          "example": "active"
                        },
                        "pass_data": {
                          "type": "object"
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "install_urls": {
                          "type": "object",
                          "properties": {
                            "universal": {
                              "type": "string",
                              "format": "uri"
                            }
                          }
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key."
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "VALIDATION_ERROR"
                    },
                    "message": {
                      "type": "string",
                      "example": "The given data was invalid."
                    },
                    "errors": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "WALLET_PASS_CREATE_FAILED"
                    },
                    "message": {
                      "type": "string",
                      "example": "Server error."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/api/public/v1/wallet-passes/{passId}": {
      "get": {
        "tags": ["Public API - Wallet Passes"],
        "summary": "Get a wallet pass",
        "description": "Retrieve detailed information about a specific wallet pass",
        "operationId": "e26ccdee36364543aa94d87c2fd08aae",
        "parameters": [
          {
            "name": "passId",
            "in": "path",
            "description": "Unique identifier of the wallet pass. Accepts either the PassKit ID (alphanumeric string, e.g., '72Fs3a9OH1Qqrmapw7aGC9') or the database ID (integer, e.g., '248'). The PassKit ID is returned when creating a pass.",
            "required": true,
            "schema": {
              "type": "string",
              "example": "72Fs3a9OH1Qqrmapw7aGC9"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Wallet pass retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Wallet pass retrieved successfully"
                    },
                    "data": {
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 248
                        },
                        "pass_id": {
                          "type": "string",
                          "example": "72Fs3a9OH1Qqrmapw7aGC9"
                        },
                        "user_id": {
                          "type": "integer",
                          "example": 103
                        },
                        "account_id": {
                          "type": "integer",
                          "example": 48
                        },
                        "template_id": {
                          "type": "integer",
                          "example": 38
                        },
                        "pass_type": {
                          "type": "string",
                          "example": "membership"
                        },
                        "status": {
                          "type": "string",
                          "example": "active"
                        },
                        "pass_data": {
                          "type": "object"
                        },
                        "is_installed": {
                          "type": "boolean",
                          "example": true
                        },
                        "installed_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "issued_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "expires_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "install_urls": {
                          "type": "object",
                          "properties": {
                            "universal": {
                              "type": "string",
                              "format": "uri"
                            }
                          }
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Wallet pass not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "WALLET_PASS_NOT_FOUND"
                    },
                    "message": {
                      "type": "string",
                      "example": "Wallet pass not found."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "WALLET_PASS_RETRIEVE_FAILED"
                    },
                    "message": {
                      "type": "string",
                      "example": "Server error."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      },
      "put": {
        "tags": ["Public API - Wallet Passes"],
        "summary": "Update a wallet pass",
        "description": "Update an existing wallet pass with new data",
        "operationId": "c2a908f2a64dfc841bc15b5bf0aedfce",
        "parameters": [
          {
            "name": "passId",
            "in": "path",
            "description": "Unique identifier of the wallet pass. Accepts either the PassKit ID (alphanumeric string, e.g., '72Fs3a9OH1Qqrmapw7aGC9') or the database ID (integer, e.g., '248'). The PassKit ID is returned when creating a pass.",
            "required": true,
            "schema": {
              "type": "string",
              "example": "72Fs3a9OH1Qqrmapw7aGC9"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "pass_data": {
                    "description": "Custom pass data fields to update",
                    "type": "object"
                  },
                  "field_values": {
                    "description": "Field values to update",
                    "type": "object"
                  },
                  "metadata": {
                    "description": "Additional metadata to update",
                    "type": "object"
                  },
                  "status": {
                    "description": "New status for the pass",
                    "type": "string",
                    "enum": ["active", "inactive", "suspended", "expired", "voided"],
                    "example": "active"
                  },
                  "expires_at": {
                    "description": "New expiration date for the pass",
                    "type": "string",
                    "format": "date-time",
                    "example": "2026-12-31T23:59:59Z"
                  }
                },
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Wallet pass updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Wallet pass updated successfully"
                    },
                    "data": {
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 248
                        },
                        "pass_id": {
                          "type": "string",
                          "example": "72Fs3a9OH1Qqrmapw7aGC9"
                        },
                        "template_id": {
                          "type": "integer",
                          "example": 38
                        },
                        "status": {
                          "type": "string",
                          "example": "active"
                        },
                        "pass_data": {
                          "type": "object"
                        },
                        "updated_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Wallet pass not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "WALLET_PASS_NOT_FOUND"
                    },
                    "message": {
                      "type": "string",
                      "example": "Wallet pass not found."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "VALIDATION_ERROR"
                    },
                    "message": {
                      "type": "string",
                      "example": "The given data was invalid."
                    },
                    "errors": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "WALLET_PASS_UPDATE_FAILED"
                    },
                    "message": {
                      "type": "string",
                      "example": "Server error."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      },
      "delete": {
        "tags": ["Public API - Wallet Passes"],
        "summary": "Delete a wallet pass",
        "description": "Permanently delete a wallet pass from the system",
        "operationId": "61e8ec297c33cd1c475f7e74fccfa02a",
        "parameters": [
          {
            "name": "passId",
            "in": "path",
            "description": "Unique identifier of the wallet pass. Accepts either the PassKit ID (alphanumeric string, e.g., '72Fs3a9OH1Qqrmapw7aGC9') or the database ID (integer, e.g., '248'). The PassKit ID is returned when creating a pass.",
            "required": true,
            "schema": {
              "type": "string",
              "example": "72Fs3a9OH1Qqrmapw7aGC9"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Wallet pass deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Wallet pass deleted successfully"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Wallet pass not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "WALLET_PASS_NOT_FOUND"
                    },
                    "message": {
                      "type": "string",
                      "example": "Wallet pass not found."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "WALLET_PASS_DELETE_FAILED"
                    },
                    "message": {
                      "type": "string",
                      "example": "Server error."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/api/public/v1/card-templates": {
      "get": {
        "tags": ["Public API - Card Templates"],
        "summary": "List card templates",
        "description": "Retrieve a paginated list of card templates with optional filtering and sorting",
        "operationId": "3e3fb953b84257819fd7b91ef8c8459d",
        "parameters": [
          {
            "name": "per_page",
            "in": "query",
            "description": "Number of items per page",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 10,
              "example": 10
            }
          },
          {
            "name": "current_page",
            "in": "query",
            "description": "Current page number",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "example": 1
            }
          },
          {
            "name": "query",
            "in": "query",
            "description": "Search query string for template name or description",
            "required": false,
            "schema": {
              "type": "string",
              "example": "membership"
            }
          },
          {
            "name": "filters[category]",
            "in": "query",
            "description": "Filter by template category",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["loyalty", "stamps", "gift_card"],
              "example": "loyalty"
            }
          },
          {
            "name": "filters[status]",
            "in": "query",
            "description": "Filter by template status",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["draft", "published", "archived"],
              "example": "published"
            }
          },
          {
            "name": "sort_by",
            "in": "query",
            "description": "Field to sort by",
            "required": false,
            "schema": {
              "type": "string",
              "default": "created_at",
              "enum": ["id", "created_at", "updated_at", "name", "status", "category"]
            }
          },
          {
            "name": "sort_order",
            "in": "query",
            "description": "Sort order",
            "required": false,
            "schema": {
              "type": "string",
              "default": "desc",
              "enum": ["asc", "desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Templates retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Templates Fetched"
                    },
                    "data": {
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "properties": {
                              "id": {
                                "type": "integer",
                                "example": 38
                              },
                              "hash_id": {
                                "type": "string",
                                "example": "abc123"
                              },
                              "name": {
                                "type": "string",
                                "example": "Loyalty Card Template"
                              },
                              "description": {
                                "type": "string",
                                "example": "A loyalty card template"
                              },
                              "template_type": {
                                "type": "string",
                                "example": "membership"
                              },
                              "category": {
                                "type": "string",
                                "example": "loyalty"
                              },
                              "status": {
                                "type": "string",
                                "example": "published"
                              },
                              "hero": {
                                "type": "string",
                                "format": "uri",
                                "nullable": true
                              },
                              "strip": {
                                "type": "string",
                                "format": "uri",
                                "nullable": true
                              },
                              "card_created_count": {
                                "type": "integer",
                                "example": 150
                              },
                              "last_used": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              },
                              "has_signup_form": {
                                "type": "boolean",
                                "example": true
                              }
                            },
                            "type": "object"
                          }
                        },
                        "meta": {
                          "properties": {
                            "current_page": {
                              "type": "integer",
                              "example": 1
                            },
                            "per_page": {
                              "type": "integer",
                              "example": 10
                            },
                            "total": {
                              "type": "integer",
                              "example": 25
                            },
                            "last_page": {
                              "type": "integer",
                              "example": 3
                            }
                          },
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "You do not have permission to view templates"
                    }
                  },
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      },
      "post": {
        "tags": ["Public API - Card Templates"],
        "summary": "Create a card template",
        "description": "Create a new card template with PassKit integration. Supports membership and coupon template types.",
        "operationId": "5b6508bd1a8248490e374dc0660ca1a0",
        "requestBody": {
          "description": "Card template data. Supports multipart/form-data for image uploads.",
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "required": ["name", "template_type", "category", "status", "timezone"],
                "properties": {
                  "name": {
                    "description": "Template name",
                    "type": "string",
                    "maxLength": 255,
                    "example": "Gold Membership Card"
                  },
                  "description": {
                    "description": "Template description",
                    "type": "string",
                    "example": "Premium membership card for VIP customers"
                  },
                  "template_type": {
                    "description": "Type of template",
                    "type": "string",
                    "enum": ["membership", "coupon"]
                  },
                  "category": {
                    "description": "Template category",
                    "type": "string",
                    "enum": ["loyalty", "stamps", "gift_card"]
                  },
                  "status": {
                    "description": "Template status",
                    "type": "string",
                    "enum": ["draft", "published", "archived"]
                  },
                  "timezone": {
                    "description": "Timezone for the template",
                    "type": "string",
                    "example": "UTC"
                  },
                  "program_id": {
                    "description": "PassKit program ID (for membership templates)",
                    "type": "string"
                  },
                  "campaign_id": {
                    "description": "PassKit campaign ID (for coupon templates)",
                    "type": "string"
                  },
                  "max_stamp_count": {
                    "description": "Maximum stamps (for stamp cards)",
                    "type": "integer",
                    "example": 10
                  },
                  "template_data": {
                    "description": "Additional template configuration",
                    "type": "object"
                  },
                  "field_definitions": {
                    "description": "Field definitions for the template",
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  },
                  "barcode_has_static": {
                    "description": "Whether barcode has static value",
                    "type": "boolean"
                  },
                  "barcode_static_value": {
                    "description": "Static barcode value",
                    "type": "string"
                  },
                  "logo_image": {
                    "description": "Logo image file. Supported formats: PNG, JPG, GIF. Max size: 2MB. Recommended: 160x50px",
                    "type": "string",
                    "format": "binary"
                  },
                  "hero_image": {
                    "description": "Hero image file. Supported formats: PNG, JPG, GIF. Max size: 2MB. Recommended: 1125x432px",
                    "type": "string",
                    "format": "binary"
                  },
                  "icon_image": {
                    "description": "Icon image file. Supported formats: PNG, JPG, GIF. Max size: 2MB. Recommended: 87x87px",
                    "type": "string",
                    "format": "binary"
                  },
                  "strip_image": {
                    "description": "Strip image file. Supported formats: PNG, JPG, GIF. Max size: 2MB. Recommended: 1125x432px",
                    "type": "string",
                    "format": "binary"
                  }
                },
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Template created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string",
                      "example": "Template created successfully!"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permission denied or template limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "You do not have permission to create templates"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "422": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "VALIDATION_ERROR"
                    },
                    "message": {
                      "type": "string",
                      "example": "The given data was invalid."
                    },
                    "errors": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "message": {
                      "type": "string",
                      "example": "Failed to create template"
                    },
                    "error": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/api/public/v1/card-templates/{templateId}": {
      "get": {
        "tags": ["Public API - Card Templates"],
        "summary": "Get a card template",
        "description": "Retrieve detailed information about a specific card template",
        "operationId": "67b998a6b7779985cc9bad82ac768dfd",
        "parameters": [
          {
            "name": "templateId",
            "in": "path",
            "description": "Unique identifier of the card template",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 38
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Template retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Template Fetched"
                    },
                    "data": {
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 38
                        },
                        "hash_id": {
                          "type": "string",
                          "example": "abc123"
                        },
                        "name": {
                          "type": "string",
                          "example": "Loyalty Card Template"
                        },
                        "description": {
                          "type": "string",
                          "example": "A loyalty card template"
                        },
                        "category": {
                          "type": "string",
                          "example": "loyalty"
                        },
                        "status": {
                          "type": "string",
                          "example": "published"
                        },
                        "template_data": {
                          "type": "object"
                        },
                        "field_definitions": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          }
                        },
                        "timezone": {
                          "type": "string",
                          "example": "UTC"
                        },
                        "fields_count": {
                          "type": "integer",
                          "example": 5
                        },
                        "images": {
                          "properties": {
                            "logo": {
                              "type": "string",
                              "format": "uri",
                              "nullable": true
                            },
                            "hero": {
                              "type": "string",
                              "format": "uri",
                              "nullable": true
                            },
                            "icon": {
                              "type": "string",
                              "format": "uri",
                              "nullable": true
                            },
                            "strip": {
                              "type": "string",
                              "format": "uri",
                              "nullable": true
                            }
                          },
                          "type": "object"
                        },
                        "max_stamps_count": {
                          "type": "integer",
                          "example": 10,
                          "nullable": true
                        },
                        "cards_count": {
                          "type": "integer",
                          "example": 150
                        },
                        "has_signup_form": {
                          "type": "boolean",
                          "example": true
                        },
                        "required_fields": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "You do not have permission to view this template"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Template not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "RESOURCE_NOT_FOUND"
                    },
                    "message": {
                      "type": "string",
                      "example": "The requested resource was not found."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      },
      "put": {
        "tags": ["Public API - Card Templates"],
        "summary": "Update a card template",
        "description": "Update an existing card template. Changes are synced to PassKit.",
        "operationId": "87d8e64c7e2217e7cc8aaa659ac19369",
        "parameters": [
          {
            "name": "templateId",
            "in": "path",
            "description": "Unique identifier of the card template",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 38
            }
          }
        ],
        "requestBody": {
          "description": "Updated template data. Supports multipart/form-data for image uploads.",
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "required": ["status"],
                "properties": {
                  "name": {
                    "description": "Template name",
                    "type": "string",
                    "maxLength": 255
                  },
                  "description": {
                    "description": "Template description",
                    "type": "string"
                  },
                  "category": {
                    "description": "Template category",
                    "type": "string",
                    "enum": ["loyalty", "stamps", "gift_card"]
                  },
                  "status": {
                    "description": "Template status",
                    "type": "string",
                    "enum": ["draft", "published", "archived"]
                  },
                  "timezone": {
                    "description": "Timezone for the template",
                    "type": "string"
                  },
                  "max_stamp_count": {
                    "description": "Maximum stamps (for stamp cards)",
                    "type": "integer"
                  },
                  "template_data": {
                    "description": "Additional template configuration",
                    "type": "object"
                  },
                  "field_definitions": {
                    "description": "Field definitions for the template",
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  },
                  "barcode_has_static": {
                    "description": "Whether barcode has static value",
                    "type": "boolean"
                  },
                  "barcode_static_value": {
                    "description": "Static barcode value",
                    "type": "string"
                  },
                  "logo_image": {
                    "description": "Logo image file. Supported formats: PNG, JPG, GIF. Max size: 2MB. Recommended: 160x50px",
                    "type": "string",
                    "format": "binary"
                  },
                  "hero_image": {
                    "description": "Hero image file. Supported formats: PNG, JPG, GIF. Max size: 2MB. Recommended: 1125x432px",
                    "type": "string",
                    "format": "binary"
                  },
                  "icon_image": {
                    "description": "Icon image file. Supported formats: PNG, JPG, GIF. Max size: 2MB. Recommended: 87x87px",
                    "type": "string",
                    "format": "binary"
                  },
                  "strip_image": {
                    "description": "Strip image file. Supported formats: PNG, JPG, GIF. Max size: 2MB. Recommended: 1125x432px",
                    "type": "string",
                    "format": "binary"
                  }
                },
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Template updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string",
                      "example": "Template updated successfully!"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "UNAUTHORIZED_ACCESS"
                    },
                    "message": {
                      "type": "string",
                      "example": "You do not have permission to update templates"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Template not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "RESOURCE_NOT_FOUND"
                    },
                    "message": {
                      "type": "string",
                      "example": "The requested resource was not found."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "message": {
                      "type": "string",
                      "example": "Failed to update template"
                    },
                    "error": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      },
      "delete": {
        "tags": ["Public API - Card Templates"],
        "summary": "Delete a card template",
        "description": "Permanently delete a card template. Also removes the template from PassKit.",
        "operationId": "c7a11d7a19abc860c42db9351d2524bf",
        "parameters": [
          {
            "name": "templateId",
            "in": "path",
            "description": "Unique identifier of the card template",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 38
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Template deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string",
                      "example": "Template deleted successfully"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid API key."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "UNAUTHORIZED_ACCESS"
                    },
                    "message": {
                      "type": "string",
                      "example": "You do not have permission to delete templates"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Template not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "boolean",
                      "example": true
                    },
                    "error_code": {
                      "type": "string",
                      "example": "RESOURCE_NOT_FOUND"
                    },
                    "message": {
                      "type": "string",
                      "example": "The requested resource was not found."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "message": {
                      "type": "string",
                      "example": "Failed to delete template from PassKit"
                    }
                  },
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "description": "API key for public API authentication. Generate API keys from your account settings in the dashboard. Include this key in the X-API-Key header for all requests.",
        "name": "X-API-Key",
        "in": "header"
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "The same API key sent as Authorization: Bearer <key>."
      }
    }
  },
  "tags": [
    {
      "name": "Public API - Notifications",
      "description": "Public API endpoints for sending push notifications to wallet passes. Requires API key authentication via the X-API-Key header. API keys can be generated from your account settings in the dashboard."
    },
    {
      "name": "Public API - Wallet Passes",
      "description": "Public API endpoints for wallet pass CRUD operations. Requires API key authentication via the X-API-Key header. API keys can be generated from your account settings in the dashboard."
    },
    {
      "name": "Public API - Card Templates",
      "description": "Public API endpoints for card template CRUD operations. Requires API key authentication via the X-API-Key header. API keys can be generated from your account settings in the dashboard."
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    },
    {
      "BearerAuth": []
    }
  ]
}
