{
  "openapi": "3.1.0",
  "info": {
    "title": "Inqued Personal Card API",
    "version": "1.0.0",
    "description": "One machine-written real-pen card mailed to a U.S. address. $3 standard; $4 rush. Secure Stripe checkout requires human payment. Creating a checkout does not send mail. Get explicit user approval of wording, address and price before submitting personal details."
  },
  "servers": [
    {
      "url": "https://inqued.com"
    }
  ],
  "paths": {
    "/api/v1/capabilities": {
      "get": {
        "operationId": "getCardCapabilities",
        "summary": "Check current prices, limits and checkout availability",
        "responses": {
          "200": {
            "description": "Capabilities and checkoutEnabled flag"
          }
        }
      }
    },
    "/api/v1/letters/quote": {
      "post": {
        "operationId": "quoteCard",
        "summary": "Price one card without submitting personal information",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "speed": {
                    "enum": [
                      "standard",
                      "rush"
                    ],
                    "default": "standard"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Quote in USD cents; taxMode indicates whether applicable tax is added by Stripe.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "currency": {
                      "const": "usd"
                    },
                    "cardCents": {
                      "const": 300
                    },
                    "rushCents": {
                      "enum": [
                        0,
                        100
                      ]
                    },
                    "subtotalCents": {
                      "enum": [
                        300,
                        400
                      ]
                    },
                    "mailingBusinessDays": {
                      "enum": [
                        1,
                        2
                      ]
                    },
                    "speed": {
                      "enum": [
                        "standard",
                        "rush"
                      ]
                    },
                    "postageIncluded": {
                      "const": true
                    },
                    "deliveryGuaranteed": {
                      "const": false
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/letters/checkout": {
      "post": {
        "operationId": "createCardCheckout",
        "summary": "Save an approved card and get a Stripe link for human payment",
        "description": "No API key required. Server-to-server JSON supported; foreign browser Origins rejected. Limit 12 attempts/IP/10 minutes. Retry identical payload with the same UUID to avoid duplicates. An expired or changed order requires a new requestId and renewed user approval. Not a payment or dispatch action.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CardOrder"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Unpaid checkout. Show url to the user to review payment.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "orderId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "quote": {
                      "type": "object",
                      "properties": {
                        "currency": {
                          "const": "usd"
                        },
                        "cardCents": {
                          "const": 300
                        },
                        "rushCents": {
                          "enum": [
                            0,
                            100
                          ]
                        },
                        "subtotalCents": {
                          "enum": [
                            300,
                            400
                          ]
                        },
                        "mailingBusinessDays": {
                          "enum": [
                            1,
                            2
                          ]
                        },
                        "speed": {
                          "enum": [
                            "standard",
                            "rush"
                          ]
                        },
                        "postageIncluded": {
                          "const": true
                        },
                        "deliveryGuaranteed": {
                          "const": false
                        }
                      }
                    },
                    "paymentRequired": {
                      "const": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait."
              }
            }
          },
          "502": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/payments/status": {
      "get": {
        "operationId": "getCardPaymentStatus",
        "summary": "Get payment and mailing state using the private Stripe session reference",
        "parameters": [
          {
            "name": "session_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^cs_(test|live)_[a-zA-Z0-9]{8,200}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Status only, no sender, address or message. Fulfillment is queued only after a verified webhook.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "enum": [
                        "paid",
                        "pending",
                        "expired"
                      ]
                    },
                    "reference": {
                      "type": "string"
                    },
                    "totalCents": {
                      "type": "integer"
                    },
                    "currency": {
                      "const": "usd"
                    },
                    "mailingBusinessDays": {
                      "enum": [
                        1,
                        2
                      ]
                    },
                    "fulfillmentStatus": {
                      "enum": [
                        "queued",
                        "mailed",
                        "awaiting_payment_confirmation"
                      ]
                    },
                    "mailedAt": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Error. No card is dispatched.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CardOrder": {
        "type": "object",
        "required": [
          "requestId",
          "sender",
          "recipient",
          "message",
          "signature",
          "speed",
          "confirmed"
        ],
        "properties": {
          "requestId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 36,
            "format": "uuid",
            "description": "UUID v4. Reuse for identical retries."
          },
          "sender": {
            "type": "object",
            "required": [
              "name",
              "email"
            ],
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "email": {
                "type": "string",
                "minLength": 1,
                "maxLength": 254,
                "format": "email"
              }
            }
          },
          "recipient": {
            "type": "object",
            "required": [
              "name",
              "address1",
              "city",
              "state",
              "postalCode",
              "country"
            ],
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "address1": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "address2": {
                "type": "string",
                "maxLength": 120
              },
              "city": {
                "type": "string",
                "minLength": 1,
                "maxLength": 80
              },
              "state": {
                "type": "string",
                "enum": [
                  "AL",
                  "AK",
                  "AZ",
                  "AR",
                  "CA",
                  "CO",
                  "CT",
                  "DE",
                  "FL",
                  "GA",
                  "HI",
                  "ID",
                  "IL",
                  "IN",
                  "IA",
                  "KS",
                  "KY",
                  "LA",
                  "ME",
                  "MD",
                  "MA",
                  "MI",
                  "MN",
                  "MS",
                  "MO",
                  "MT",
                  "NE",
                  "NV",
                  "NH",
                  "NJ",
                  "NM",
                  "NY",
                  "NC",
                  "ND",
                  "OH",
                  "OK",
                  "OR",
                  "PA",
                  "RI",
                  "SC",
                  "SD",
                  "TN",
                  "TX",
                  "UT",
                  "VT",
                  "VA",
                  "WA",
                  "WV",
                  "WI",
                  "WY",
                  "DC"
                ]
              },
              "postalCode": {
                "type": "string",
                "minLength": 1,
                "maxLength": 10,
                "pattern": "^\\d{5}(-\\d{4})?$"
              },
              "country": {
                "const": "US"
              }
            }
          },
          "message": {
            "type": "string",
            "minLength": 1,
            "maxLength": 400,
            "description": "At most 10 lines and no word longer than 40 characters. Include greeting in message."
          },
          "signature": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50,
            "description": "No word longer than 30 characters."
          },
          "speed": {
            "enum": [
              "standard",
              "rush"
            ]
          },
          "confirmed": {
            "const": true,
            "description": "The user has approved wording, destination and price."
          }
        }
      }
    }
  }
}
