{
  "openapi": "3.0.0",
  "info": {
    "title": "ReloadCard API",
    "version": "1.0.0",
    "description": "Gift card management API for any POS, e-commerce, or custom integration.",
    "contact": {
      "email": "support@reloadcard.app"
    }
  },
  "servers": [
    {
      "url": "https://merchant.reloadcard.app/api/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key (rc_live_...)"
      }
    },
    "schemas": {
      "Card": {
        "type": "object",
        "properties": {
          "uuid": { "type": "string", "format": "uuid" },
          "code": { "type": "string" },
          "currency": { "type": "string", "example": "USD" },
          "balanceCents": { "type": "integer", "example": 5000 },
          "status": { "type": "string", "enum": ["active", "inactive", "disabled"] },
          "cardType": { "type": "string", "enum": ["digital", "physical"] },
          "ownerEmail": { "type": "string", "format": "email" },
          "merchantId": { "type": "string", "format": "uuid" },
          "createdAt": { "type": "string", "format": "date-time" },
          "updatedAt": { "type": "string", "format": "date-time" }
        }
      },
      "Transaction": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "cardUuid": { "type": "string", "format": "uuid" },
          "type": { "type": "string", "enum": ["load", "spend", "transfer_in", "transfer_out", "gift_sent", "gift_received"] },
          "amountCents": { "type": "integer", "example": 1500 },
          "currency": { "type": "string", "example": "USD" },
          "description": { "type": "string" },
          "status": { "type": "string", "enum": ["completed", "pending", "failed"] },
          "createdAt": { "type": "string", "format": "date-time" }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "url": { "type": "string", "format": "uri" },
          "events": {
            "type": "array",
            "items": { "type": "string" },
            "example": ["card.activated", "card.debited"]
          },
          "active": { "type": "boolean" },
          "createdAt": { "type": "string", "format": "date-time" }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": { "type": "string" },
          "message": { "type": "string" }
        }
      }
    },
    "parameters": {
      "CardUuid": {
        "name": "uuid",
        "in": "path",
        "required": true,
        "schema": { "type": "string", "format": "uuid" },
        "description": "Card UUID"
      },
      "WebhookId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": { "type": "string", "format": "uuid" },
        "description": "Webhook ID"
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "schema": { "type": "integer", "default": 20, "maximum": 100 },
        "description": "Number of results to return"
      },
      "Offset": {
        "name": "offset",
        "in": "query",
        "schema": { "type": "integer", "default": 0 },
        "description": "Number of results to skip"
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "schema": { "type": "string", "format": "uuid" },
        "description": "Unique key to prevent duplicate operations (valid for 24 hours)"
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Bad request — check your parameters",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      },
      "Unauthorized": {
        "description": "Unauthorized — invalid or missing API key",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      },
      "NotFound": {
        "description": "Not found — card or resource does not exist or does not belong to you",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limited — slow down",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      }
    }
  },
  "paths": {
    "/cards": {
      "get": {
        "summary": "List all cards",
        "description": "Returns a paginated list of gift cards belonging to your merchant account.",
        "operationId": "listCards",
        "tags": ["Cards"],
        "parameters": [
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" },
          {
            "name": "status",
            "in": "query",
            "schema": { "type": "string", "enum": ["active", "inactive", "disabled"] },
            "description": "Filter by card status"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of cards",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "cards": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Card" }
                    },
                    "total": { "type": "integer" },
                    "limit": { "type": "integer" },
                    "offset": { "type": "integer" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "summary": "Create a new card",
        "description": "Creates a new gift card. The card is created in an inactive state and must be activated separately.",
        "operationId": "createCard",
        "tags": ["Cards"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["currency"],
                "properties": {
                  "currency": { "type": "string", "example": "USD", "description": "ISO 4217 currency code" },
                  "cardType": { "type": "string", "enum": ["digital", "physical"], "default": "digital" },
                  "ownerEmail": { "type": "string", "format": "email", "description": "Email of the card recipient" }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Card created",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Card" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/cards/{uuid}": {
      "get": {
        "summary": "Get card details",
        "description": "Returns full card details including recent transactions.",
        "operationId": "getCard",
        "tags": ["Cards"],
        "parameters": [
          { "$ref": "#/components/parameters/CardUuid" }
        ],
        "responses": {
          "200": {
            "description": "Card details",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Card" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/cards/{uuid}/activate": {
      "post": {
        "summary": "Activate a card",
        "description": "Activates an inactive card with an initial balance.",
        "operationId": "activateCard",
        "tags": ["Cards"],
        "parameters": [
          { "$ref": "#/components/parameters/CardUuid" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["amountCents"],
                "properties": {
                  "amountCents": { "type": "integer", "minimum": 1, "example": 5000, "description": "Initial balance in cents" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Card activated",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Card" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/cards/{uuid}/debit": {
      "post": {
        "summary": "Debit card balance",
        "description": "Deducts from the card balance. Use for POS redemptions. Supports idempotency keys.",
        "operationId": "debitCard",
        "tags": ["Cards"],
        "parameters": [
          { "$ref": "#/components/parameters/CardUuid" },
          { "$ref": "#/components/parameters/IdempotencyKey" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["amountCents"],
                "properties": {
                  "amountCents": { "type": "integer", "minimum": 1, "example": 1500, "description": "Amount to debit in cents" },
                  "note": { "type": "string", "example": "Order #1234", "description": "Optional note for the transaction" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Debit successful",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "card": { "$ref": "#/components/schemas/Card" },
                    "transaction": { "$ref": "#/components/schemas/Transaction" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/cards/{uuid}/credit": {
      "post": {
        "summary": "Credit card balance",
        "description": "Adds to the card balance. Use for refunds or manual top-ups. Supports idempotency keys.",
        "operationId": "creditCard",
        "tags": ["Cards"],
        "parameters": [
          { "$ref": "#/components/parameters/CardUuid" },
          { "$ref": "#/components/parameters/IdempotencyKey" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["amountCents"],
                "properties": {
                  "amountCents": { "type": "integer", "minimum": 1, "example": 2000, "description": "Amount to credit in cents" },
                  "note": { "type": "string", "example": "Refund for order #1234", "description": "Optional note for the transaction" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Credit successful",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "card": { "$ref": "#/components/schemas/Card" },
                    "transaction": { "$ref": "#/components/schemas/Transaction" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/cards/{uuid}/balance": {
      "get": {
        "summary": "Check card balance",
        "description": "Returns the current balance for a card.",
        "operationId": "getCardBalance",
        "tags": ["Cards"],
        "parameters": [
          { "$ref": "#/components/parameters/CardUuid" }
        ],
        "responses": {
          "200": {
            "description": "Balance response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "uuid": { "type": "string", "format": "uuid" },
                    "balanceCents": { "type": "integer", "example": 3500 },
                    "currency": { "type": "string", "example": "USD" },
                    "status": { "type": "string", "enum": ["active", "inactive", "disabled"] }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/cards/{uuid}/disable": {
      "post": {
        "summary": "Disable a card",
        "description": "Suspends a card, preventing further transactions. This action is permanent.",
        "operationId": "disableCard",
        "tags": ["Cards"],
        "parameters": [
          { "$ref": "#/components/parameters/CardUuid" }
        ],
        "responses": {
          "200": {
            "description": "Card disabled",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Card" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/cards/{uuid}/claim": {
      "post": {
        "summary": "Claim a pre-loaded card",
        "description": "Claims a pre-loaded card by associating it with the authenticated consumer account.",
        "operationId": "claimCard",
        "tags": ["Cards"],
        "parameters": [
          { "$ref": "#/components/parameters/CardUuid" }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "claimCode": { "type": "string", "description": "Optional claim code printed on the physical card" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Card claimed successfully",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Card" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/transactions": {
      "get": {
        "summary": "List transactions",
        "description": "Returns a paginated list of all transactions across your merchant cards.",
        "operationId": "listTransactions",
        "tags": ["Transactions"],
        "parameters": [
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of transactions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transactions": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Transaction" }
                    },
                    "total": { "type": "integer" },
                    "limit": { "type": "integer" },
                    "offset": { "type": "integer" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/store-credit": {
      "post": {
        "summary": "Issue store credit",
        "description": "Issues store credit to a consumer by email. Creates a card if one does not exist for this merchant.",
        "operationId": "issueStoreCredit",
        "tags": ["Store Credit"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email", "amountCents", "currency"],
                "properties": {
                  "email": { "type": "string", "format": "email", "description": "Consumer email address" },
                  "amountCents": { "type": "integer", "minimum": 1, "example": 1000, "description": "Amount in cents" },
                  "currency": { "type": "string", "example": "USD", "description": "ISO 4217 currency code" },
                  "note": { "type": "string", "description": "Reason for the credit (visible to consumer)" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Store credit issued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "card": { "$ref": "#/components/schemas/Card" },
                    "transaction": { "$ref": "#/components/schemas/Transaction" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/webhooks": {
      "get": {
        "summary": "List webhooks",
        "description": "Returns all webhook subscriptions for your merchant account.",
        "operationId": "listWebhooks",
        "tags": ["Webhooks"],
        "responses": {
          "200": {
            "description": "List of webhooks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "webhooks": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Webhook" }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "summary": "Create a webhook",
        "description": "Registers a new webhook subscription for specific events.",
        "operationId": "createWebhook",
        "tags": ["Webhooks"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["url", "events"],
                "properties": {
                  "url": { "type": "string", "format": "uri", "example": "https://example.com/webhooks/reloadcard", "description": "HTTPS endpoint to receive webhook events" },
                  "events": {
                    "type": "array",
                    "items": { "type": "string" },
                    "example": ["card.activated", "card.debited", "card.credited"],
                    "description": "Event types to subscribe to"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook created",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Webhook" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/webhooks/{id}": {
      "patch": {
        "summary": "Update a webhook",
        "description": "Updates an existing webhook subscription. You can change the URL, events, or active status.",
        "operationId": "updateWebhook",
        "tags": ["Webhooks"],
        "parameters": [
          { "$ref": "#/components/parameters/WebhookId" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": { "type": "string", "format": "uri", "description": "New webhook URL" },
                  "events": {
                    "type": "array",
                    "items": { "type": "string" },
                    "description": "Updated event types"
                  },
                  "active": { "type": "boolean", "description": "Enable or disable the webhook" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook updated",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Webhook" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "delete": {
        "summary": "Delete a webhook",
        "description": "Permanently deletes a webhook subscription. This action cannot be undone.",
        "operationId": "deleteWebhook",
        "tags": ["Webhooks"],
        "parameters": [
          { "$ref": "#/components/parameters/WebhookId" }
        ],
        "responses": {
          "200": {
            "description": "Webhook deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "tags": [
    { "name": "Cards", "description": "Create, manage, and transact on gift cards" },
    { "name": "Transactions", "description": "View transaction history" },
    { "name": "Store Credit", "description": "Issue store credit to consumers" },
    { "name": "Webhooks", "description": "Manage webhook subscriptions for real-time event notifications" }
  ]
}
