{
  "openapi": "3.0.1",
  "info": {
    "title": "NachoNacho Public API",
    "version": "1.0.0",
    "description": "The NachoNacho Public API allows you to programmatically access the NachoNacho platform.\n"
  },
  "servers": [
    {
      "url": "https://public-api.nachonacho.com",
      "description": "Production"
    },
    {
      "url": "https://public-api.nachonacho.co",
      "description": "Staging"
    },
    {
      "url": "http://localhost:3037",
      "description": "Local development"
    }
  ],
  "tags": [
    {
      "name": "Authentication",
      "description": "Authenticate with the NachoNacho Public API and exchange an API key for a short-lived JWT."
    },
    {
      "name": "Provisioning",
      "description": "To access these endpoints, you must use a Seller account. Exchange a buyer activation token for a NachoNacho subscription ID, then fetch the related subscription details."
    },
    {
      "name": "NachoPay",
      "description": "NachoPay is a variant of Provisioning for products that are not sold as a fixed recurring plan — usage-based pricing, metered products, variable seat counts, one-off professional services.\n\nIt reuses the whole Provisioning setup: the same API key and JWT, the same Token exchange URL, and the same `POST /tokens/resolve` handshake — those two endpoints are listed here as well, because you need them for NachoPay exactly as you would for Provisioning. The only difference is how money moves. There are no pricing tiers and no Stripe subscription: the Buyer saves a payment source once at checkout, and from then on you decide when and how much to bill with `POST /payments`, and can give a charge back in full with `POST /payments/{paymentId}/refund`."
    },
    {
      "name": "Products",
      "description": "Browse NachoNacho marketplace products and product metadata available through the public API. \n**Note:** To access this feature, you must have a Tribe account."
    }
  ],
  "paths": {
    "/auth": {
      "post": {
        "summary": "Authenticate with API key",
        "description": "Exchange a NachoNacho API key for a short-lived JWT.\n\n## Authentication Flow\n1. Obtain an API key from your [NachoNacho account dashboard](https://app.nachonacho.com/settings/api) (format: `NN_live_<key>`)\n2. Call `POST /auth` with your API key to receive a short-lived JWT\n3. Use that JWT as a `Bearer` token on all subsequent requests",
        "tags": [
          "Authentication"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "apiKey"
                ],
                "properties": {
                  "apiKey": {
                    "type": "string",
                    "description": "Your NachoNacho API key (format NN_live_&lt;key&gt;)",
                    "example": "NN_live_9W..."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JWT token issued successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "access_token": {
                      "type": "string",
                      "description": "JWT to use as Bearer token on subsequent requests",
                      "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tokens/resolve": {
      "post": {
        "summary": "Resolve provisioning token",
        "description": "After the buyer completes payment for your product in NachoNacho, they are prompted to return to your website by clicking a button that includes a token in the URL, for example: https://yoursite.com?NN_token=NN_claim_Ddpu...2751df9. Resolve this one-time provisioning token for a NachoNacho subscription ID, then save that subscription ID in your database and associate it with the user. Use the subscription ID with GET /subscriptions/{subscriptionId} to retrieve subscription details whenever you need to check whether the buyer has an active subscription.\n",
        "tags": [
          "Provisioning",
          "NachoPay"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "token"
                ],
                "properties": {
                  "token": {
                    "type": "string",
                    "description": "One-time token provided by the buyer during Provisioning flow",
                    "example": "NN_claim_Ddpu..."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token resolved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "subscriptionId": {
                      "type": "string",
                      "description": "NachoNacho subscription ID (use with GET /subscriptions/{subscriptionId})",
                      "example": "cmmcoxge20001cnsppobu1anr"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing token in body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid token, expired token, or missing/invalid Authorization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Seller is not the owner of this product",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/subscriptions/{subscriptionId}": {
      "get": {
        "summary": "Get subscription details",
        "description": "Retrieve details for a NachoNacho subscription whenever you need to verify whether the buyer is still a paying customer. You can call this endpoint at login, once a month, or any other time required by your business logic.\nUse the NachoNacho subscription ID to fetch the subscription details.\n\nThe response shape depends on the flow the subscription belongs to, given by the `type` field:\n- `PROVISIONING`: `subscription_payment` holds the Stripe subscription object. For additional subscription fields, see the [Stripe API documentation](https://stripe.com/docs/api/subscriptions/object).\n- `NACHO_PAY`: there is no Stripe subscription, so `subscription_payment` is `null`. Use `payment_source` and `can_be_charged` to check that the buyer still has a payment source you can bill through `POST /payments`.",
        "tags": [
          "Provisioning",
          "NachoPay"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "subscriptionId",
            "in": "path",
            "required": true,
            "description": "NachoNacho subscription ID (from POST /tokens/resolve response)",
            "schema": {
              "type": "string",
              "example": "cmmcoxge20001cnsppobu1anr"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Subscription details with user, company, and — for PROVISIONING subscriptions — Stripe subscription data",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Response from GET /subscriptions/{subscriptionId}",
                  "properties": {
                    "subscriptionId": {
                      "type": "string",
                      "example": "cmmcoxge20001cnsppobu1anr"
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "PROVISIONING",
                        "NACHO_PAY"
                      ],
                      "description": "Which flow this subscription belongs to. Determines whether `subscription_payment` or `payment_source` is populated.",
                      "example": "NACHO_PAY"
                    },
                    "created": {
                      "type": "integer",
                      "description": "NACHO_PAY only. Unix timestamp of when the NachoNacho subscription was created.",
                      "example": 1785312000
                    },
                    "can_be_charged": {
                      "type": "boolean",
                      "description": "NACHO_PAY only. True when the buyer has a payment source on file and has not canceled, meaning `POST /payments` will work.",
                      "example": true
                    },
                    "payment_source": {
                      "type": "object",
                      "nullable": true,
                      "description": "NACHO_PAY only. The payment source we charge for this subscription, or null if the buyer has not saved one yet.",
                      "properties": {
                        "id": {
                          "type": "string",
                          "example": "pm_1TzXfFBIVxOUngQDuTo9rYAB"
                        },
                        "type": {
                          "type": "string",
                          "example": "card"
                        },
                        "brand": {
                          "type": "string",
                          "nullable": true,
                          "example": "visa"
                        },
                        "last4": {
                          "type": "string",
                          "nullable": true,
                          "example": "4242"
                        },
                        "exp_month": {
                          "type": "integer",
                          "nullable": true,
                          "example": 1
                        },
                        "exp_year": {
                          "type": "integer",
                          "nullable": true,
                          "example": 2029
                        }
                      }
                    },
                    "user": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "example": "clxx123abc"
                        },
                        "firstName": {
                          "type": "string",
                          "example": "Jane"
                        },
                        "lastName": {
                          "type": "string",
                          "example": "Doe"
                        },
                        "email": {
                          "type": "string",
                          "format": "email",
                          "example": "jane@example.com"
                        }
                      }
                    },
                    "company": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "example": "clxx456def"
                        },
                        "name": {
                          "type": "string",
                          "example": "Acme Inc"
                        }
                      }
                    },
                    "subscription_payment": {
                      "type": "object",
                      "nullable": true,
                      "description": "Stripe subscription object. Always null for NACHO_PAY subscriptions, which have no Stripe subscription.",
                      "properties": {
                        "id": {
                          "type": "string",
                          "example": "sub_1234567890"
                        },
                        "object": {
                          "type": "string",
                          "example": "subscription"
                        },
                        "application": {
                          "type": "string",
                          "nullable": true
                        },
                        "application_fee_percent": {
                          "type": "number",
                          "format": "float",
                          "nullable": true
                        },
                        "automatic_tax": {
                          "type": "object",
                          "properties": {
                            "enabled": {
                              "type": "boolean",
                              "example": false
                            },
                            "liability": {
                              "type": "string",
                              "nullable": true
                            }
                          }
                        },
                        "billing_cycle_anchor": {
                          "type": "integer",
                          "description": "Unix timestamp"
                        },
                        "cancel_at": {
                          "type": "integer",
                          "nullable": true,
                          "description": "Unix timestamp when subscription will cancel"
                        },
                        "cancellation_details": {
                          "type": "object",
                          "nullable": true,
                          "properties": {
                            "comment": {
                              "type": "string",
                              "nullable": true
                            },
                            "feedback": {
                              "type": "string",
                              "nullable": true
                            },
                            "reason": {
                              "type": "string",
                              "nullable": true
                            }
                          }
                        },
                        "cancel_at_period_end": {
                          "type": "boolean",
                          "example": false
                        },
                        "canceled_at": {
                          "type": "integer",
                          "nullable": true,
                          "description": "Unix timestamp when subscription was canceled"
                        },
                        "collection_method": {
                          "type": "string",
                          "example": "charge_automatically"
                        },
                        "created": {
                          "type": "integer",
                          "description": "Unix timestamp"
                        },
                        "currency": {
                          "type": "string",
                          "example": "usd"
                        },
                        "customer": {
                          "type": "string",
                          "example": "cus_Na6dX7aXxi11N4"
                        },
                        "days_until_due": {
                          "type": "integer",
                          "nullable": true
                        },
                        "default_payment_method": {
                          "type": "string",
                          "nullable": true
                        },
                        "default_source": {
                          "type": "string",
                          "nullable": true
                        },
                        "default_tax_rates": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          }
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "discounts": {
                          "type": "array",
                          "nullable": true,
                          "items": {
                            "type": "object"
                          }
                        },
                        "ended_at": {
                          "type": "integer",
                          "nullable": true
                        },
                        "invoice_settings": {
                          "type": "object",
                          "properties": {
                            "issuer": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "type": "string",
                                  "example": "self"
                                }
                              }
                            }
                          }
                        },
                        "items": {
                          "type": "object",
                          "properties": {
                            "object": {
                              "type": "string",
                              "example": "list"
                            },
                            "data": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "example": "si_Na6dzxczY5fwHx"
                                  },
                                  "object": {
                                    "type": "string",
                                    "example": "subscription_item"
                                  },
                                  "created": {
                                    "type": "integer",
                                    "description": "Unix timestamp"
                                  },
                                  "current_period_end": {
                                    "type": "integer",
                                    "description": "Unix timestamp"
                                  },
                                  "current_period_start": {
                                    "type": "integer",
                                    "description": "Unix timestamp"
                                  },
                                  "metadata": {
                                    "type": "object",
                                    "additionalProperties": true
                                  },
                                  "plan": {
                                    "type": "object",
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "example": "price_1MowQULkdIwHu7ixraBm864M"
                                      },
                                      "object": {
                                        "type": "string",
                                        "example": "plan"
                                      },
                                      "active": {
                                        "type": "boolean",
                                        "example": true
                                      },
                                      "amount": {
                                        "type": "integer",
                                        "example": 1000
                                      },
                                      "amount_decimal": {
                                        "type": "string",
                                        "example": "1000"
                                      },
                                      "billing_scheme": {
                                        "type": "string",
                                        "example": "per_unit"
                                      },
                                      "created": {
                                        "type": "integer",
                                        "description": "Unix timestamp"
                                      },
                                      "currency": {
                                        "type": "string",
                                        "example": "usd"
                                      },
                                      "discounts": {
                                        "type": "array",
                                        "nullable": true,
                                        "items": {
                                          "type": "object"
                                        }
                                      },
                                      "interval": {
                                        "type": "string",
                                        "example": "month"
                                      },
                                      "interval_count": {
                                        "type": "integer",
                                        "example": 1
                                      },
                                      "livemode": {
                                        "type": "boolean",
                                        "example": false
                                      },
                                      "metadata": {
                                        "type": "object",
                                        "additionalProperties": true
                                      },
                                      "nickname": {
                                        "type": "string",
                                        "nullable": true
                                      },
                                      "product": {
                                        "type": "string",
                                        "example": "prod_Na6dGcTsmU0I4R"
                                      },
                                      "tiers_mode": {
                                        "type": "string",
                                        "nullable": true
                                      },
                                      "transform_usage": {
                                        "type": "object",
                                        "nullable": true
                                      },
                                      "trial_period_days": {
                                        "type": "integer",
                                        "nullable": true
                                      },
                                      "usage_type": {
                                        "type": "string",
                                        "example": "licensed"
                                      }
                                    }
                                  },
                                  "price": {
                                    "type": "object",
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "example": "price_1MowQULkdIwHu7ixraBm864M"
                                      },
                                      "object": {
                                        "type": "string",
                                        "example": "price"
                                      },
                                      "active": {
                                        "type": "boolean",
                                        "example": true
                                      },
                                      "billing_scheme": {
                                        "type": "string",
                                        "example": "per_unit"
                                      },
                                      "created": {
                                        "type": "integer",
                                        "description": "Unix timestamp"
                                      },
                                      "currency": {
                                        "type": "string",
                                        "example": "usd"
                                      },
                                      "custom_unit_amount": {
                                        "type": "object",
                                        "nullable": true
                                      },
                                      "livemode": {
                                        "type": "boolean",
                                        "example": false
                                      },
                                      "lookup_key": {
                                        "type": "string",
                                        "nullable": true
                                      },
                                      "metadata": {
                                        "type": "object",
                                        "additionalProperties": true
                                      },
                                      "nickname": {
                                        "type": "string",
                                        "nullable": true
                                      },
                                      "product": {
                                        "type": "string",
                                        "example": "prod_Na6dGcTsmU0I4R"
                                      },
                                      "recurring": {
                                        "type": "object",
                                        "properties": {
                                          "interval": {
                                            "type": "string",
                                            "example": "month"
                                          },
                                          "interval_count": {
                                            "type": "integer",
                                            "example": 1
                                          },
                                          "trial_period_days": {
                                            "type": "integer",
                                            "nullable": true
                                          },
                                          "usage_type": {
                                            "type": "string",
                                            "example": "licensed"
                                          }
                                        }
                                      },
                                      "tax_behavior": {
                                        "type": "string",
                                        "example": "unspecified"
                                      },
                                      "tiers_mode": {
                                        "type": "string",
                                        "nullable": true
                                      },
                                      "transform_quantity": {
                                        "type": "object",
                                        "nullable": true
                                      },
                                      "type": {
                                        "type": "string",
                                        "example": "recurring"
                                      },
                                      "unit_amount": {
                                        "type": "integer",
                                        "example": 1000
                                      },
                                      "unit_amount_decimal": {
                                        "type": "string",
                                        "example": "1000"
                                      }
                                    }
                                  },
                                  "quantity": {
                                    "type": "integer",
                                    "example": 1
                                  },
                                  "subscription": {
                                    "type": "string",
                                    "example": "sub_1MowQVLkdIwHu7ixeRlqHVzs"
                                  },
                                  "tax_rates": {
                                    "type": "array",
                                    "items": {
                                      "type": "object"
                                    }
                                  }
                                }
                              }
                            },
                            "has_more": {
                              "type": "boolean",
                              "example": false
                            },
                            "total_count": {
                              "type": "integer",
                              "example": 1
                            },
                            "url": {
                              "type": "string",
                              "example": "/v1/subscription_items?subscription=sub_1MowQVLkdIwHu7ixeRlqHVzs"
                            }
                          }
                        },
                        "latest_invoice": {
                          "type": "string",
                          "example": "in_1MowQWLkdIwHu7ixuzkSPfKd"
                        },
                        "livemode": {
                          "type": "boolean",
                          "example": false
                        },
                        "metadata": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "next_pending_invoice_item_invoice": {
                          "type": "string",
                          "nullable": true
                        },
                        "on_behalf_of": {
                          "type": "string",
                          "nullable": true
                        },
                        "pause_collection": {
                          "type": "object",
                          "nullable": true
                        },
                        "payment_settings": {
                          "type": "object",
                          "properties": {
                            "payment_method_options": {
                              "type": "object",
                              "nullable": true
                            },
                            "payment_method_types": {
                              "type": "array",
                              "nullable": true,
                              "items": {
                                "type": "string"
                              }
                            },
                            "save_default_payment_method": {
                              "type": "string",
                              "example": "off"
                            }
                          }
                        },
                        "pending_invoice_item_interval": {
                          "type": "object",
                          "nullable": true
                        },
                        "pending_setup_intent": {
                          "type": "string",
                          "nullable": true
                        },
                        "pending_update": {
                          "type": "object",
                          "nullable": true
                        },
                        "schedule": {
                          "type": "string",
                          "nullable": true
                        },
                        "start_date": {
                          "type": "integer",
                          "description": "Unix timestamp"
                        },
                        "status": {
                          "type": "string",
                          "example": "active"
                        },
                        "test_clock": {
                          "type": "string",
                          "nullable": true
                        },
                        "transfer_data": {
                          "type": "object",
                          "nullable": true
                        },
                        "trial_end": {
                          "type": "integer",
                          "nullable": true
                        },
                        "trial_settings": {
                          "type": "object",
                          "properties": {
                            "end_behavior": {
                              "type": "object",
                              "properties": {
                                "missing_payment_method": {
                                  "type": "string",
                                  "example": "create_invoice"
                                }
                              }
                            }
                          }
                        },
                        "trial_start": {
                          "type": "integer",
                          "nullable": true
                        }
                      }
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "canceled"
                      ],
                      "description": "NACHO_PAY only. `canceled` once the Buyer has ended the subscription. Cancellation is final: a canceled subscription can never be charged or reactivated.",
                      "example": "active"
                    },
                    "canceled_at": {
                      "type": "integer",
                      "nullable": true,
                      "description": "NACHO_PAY only. Unix timestamp of when the Buyer canceled, or null if still active.",
                      "example": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing subscriptionId in path or subscription has no linked Stripe subscription",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid JWT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Seller is not the owner of this product",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Subscription not found or Stripe subscription not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/payments": {
      "post": {
        "summary": "Charge a NachoPay buyer",
        "description": "Charge a Buyer on a NachoPay subscription. Send the amount you want to bill and NachoNacho charges the Buyer's saved payment source off-session, then reports what was actually taken.\n\n## Where this fits in the NachoPay flow\n1. The Buyer subscribes to your product in NachoNacho and completes a checkout that only saves a payment source — no money moves and no plan is created.\n2. The Buyer is redirected to your app through your Token exchange URL with a single-use `NN_token`.\n3. You call `POST /tokens/resolve` server-side to turn that token into a NachoNacho `subscriptionId`, and store it against your own customer record.\n4. From then on, **you** decide when to bill. Every time you want money — at the end of a usage period, when a metered threshold is crossed, when a job completes — you call this endpoint with that `subscriptionId`.\n\nThere is no Stripe subscription behind a NachoPay subscription, so nothing is ever billed automatically. If you never call this endpoint, the Buyer is never charged.\n\n## How the amounts work\nTwo percentages are configured on your Seller account (NachoPay Settings in your NachoNacho dashboard):\n- `buyerDiscountPercentage`: the discount NachoNacho applies to your requested amount to get the amount actually charged to the Buyer.\n- `revsharePercentage`: the revshare fee you pay NachoNacho, taken off your requested amount. What is left is paid out to you.\n\nFor example, with a 20% buyer discount and a 30% revshare, requesting `amount: 100` charges the Buyer $80 and pays you $70, with $30 kept by NachoNacho as the revshare fee. Send the price you would normally charge the customer — never apply the discount yourself, or it is taken twice. Payouts are handled outside of this endpoint.\n\nThe percentages in force at the moment of the call are recorded on the payment, so later changes to your account never rewrite past charges.\n\n## Prerequisites\n- The subscription must be a NachoPay subscription and belong to a product you own.\n- The Buyer must have completed the NachoPay checkout so a payment source is on file. Check `can_be_charged` on `GET /subscriptions/{subscriptionId}` if you want to verify this before billing.\n- The Buyer must not have canceled the subscription. Cancellation is final and irreversible: once canceled, every charge is refused. `GET /subscriptions/{subscriptionId}` reports it as `canceled`, and `can_be_charged` turns false.\n\n## Things to know\n- `amount` is in US dollars, must be greater than 0 and no more than 1000.\n- The charge is off-session, so a card that needs authentication is declined rather than prompting the Buyer. A decline returns `402` with the Stripe reason and the `paymentId` so you can reconcile it.\n- This endpoint is **not idempotent**: calling it twice bills the Buyer twice. Retry only when you did not receive a response, and use `externalReference` to recognise your own charges afterwards.\n- Every charge appears to the Seller under NachoPay > Transactions and to the Buyer on their subscription page, whether it succeeded or failed.\n",
        "tags": [
          "NachoPay"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subscriptionId",
                  "amount"
                ],
                "properties": {
                  "subscriptionId": {
                    "type": "string",
                    "description": "NachoNacho subscription ID (from POST /tokens/resolve response)",
                    "example": "cmmcoxge20001cnsppobu1anr"
                  },
                  "amount": {
                    "type": "number",
                    "format": "float",
                    "description": "The amount you want to bill, in US dollars. Must be greater than 0 and no more than 1000. The Buyer is charged this amount minus your configured buyer discount.",
                    "exclusiveMinimum": 0,
                    "maximum": 1000,
                    "example": 100
                  },
                  "description": {
                    "type": "string",
                    "description": "Optional description shown on the Buyer's Stripe receipt. Truncated to 350 characters.",
                    "example": "Usage for July 2026"
                  },
                  "externalReference": {
                    "type": "string",
                    "description": "Optional identifier of your own, stored on the payment metadata. Truncated to 200 characters.",
                    "example": "invoice_8842"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment created and confirmed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "paymentId": {
                      "type": "string",
                      "description": "Stripe PaymentIntent ID",
                      "example": "pi_3QabcDEfGhIjKlMn0PqRsTuV"
                    },
                    "status": {
                      "type": "string",
                      "description": "Stripe PaymentIntent status. See the [Stripe API documentation](https://stripe.com/docs/api/payment_intents/object).",
                      "example": "succeeded"
                    },
                    "subscriptionId": {
                      "type": "string",
                      "example": "cmmcoxge20001cnsppobu1anr"
                    },
                    "currency": {
                      "type": "string",
                      "example": "USD"
                    },
                    "amountRequested": {
                      "type": "number",
                      "format": "float",
                      "description": "The amount you asked to bill",
                      "example": 100
                    },
                    "amountChargedToBuyer": {
                      "type": "number",
                      "format": "float",
                      "description": "The amount actually charged to the Buyer, after the buyer discount",
                      "example": 80
                    },
                    "buyerDiscountPercentage": {
                      "type": "number",
                      "format": "float",
                      "example": 20
                    },
                    "revsharePercentage": {
                      "type": "number",
                      "format": "float",
                      "example": 30,
                      "description": "The revshare fee percentage you pay NachoNacho."
                    },
                    "revshareAmount": {
                      "type": "number",
                      "format": "float",
                      "description": "The revshare fee kept by NachoNacho for this payment.",
                      "example": 30
                    },
                    "sellerPayoutAmount": {
                      "type": "number",
                      "format": "float",
                      "description": "The amount paid out to you for this payment: your requested amount minus the revshare fee.",
                      "example": 70
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid `subscriptionId`, `amount` missing / not positive / above the $1000 maximum, subscription is not a NachoPay subscription, the Buyer canceled the subscription, Buyer has no saved payment source, or the Buyer company has no Stripe customer",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid JWT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The Buyer's payment source was declined",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Your card was declined."
                    },
                    "code": {
                      "type": "string",
                      "nullable": true,
                      "example": "card_declined"
                    },
                    "paymentId": {
                      "type": "string",
                      "example": "pi_3QabcDEfGhIjKlMn0PqRsTuV"
                    },
                    "status": {
                      "type": "string",
                      "example": "requires_payment_method"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Seller is not the owner of this product",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Subscription not found or Seller company not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/categories": {
      "get": {
        "summary": "List product categories",
        "description": "Returns the publicly visible NachoNacho marketplace product categories. Use a category `id` from this endpoint with the `categoryProductId` query parameter on `GET /products` to filter products by category.\n",
        "tags": [
          "Products"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of public product categories",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "categories": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "example": "clxx123abc"
                          },
                          "name": {
                            "type": "string",
                            "example": "Business Banking & Fintech"
                          },
                          "level": {
                            "type": "integer",
                            "description": "Category hierarchy level.",
                            "example": 1
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid JWT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Company must be a Tribe account and approved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Company not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/products": {
      "get": {
        "summary": "List marketplace products",
        "description": "Returns a paginated list of publicly visible NachoNacho marketplace products.\n",
        "tags": [
          "Products"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (1-based). Defaults to 1 if omitted.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "example": 1
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Filter products by name or short description",
            "schema": {
              "type": "string",
              "example": "slack"
            }
          },
          {
            "name": "categoryProductId",
            "in": "query",
            "required": false,
            "description": "Filter products to those positioned in a specific public category. Use an `id` returned by `GET /categories`.",
            "schema": {
              "type": "string",
              "example": "clxx123abc"
            }
          },
          {
            "name": "relationshipType",
            "in": "query",
            "required": false,
            "description": "Filter products by relationship type. Must be sent as a repeated query parameter array, for example `relationshipType=DIRECT&relationshipType=AFFILIATE`.\n\nRelationship type values:\n- `AFFILIATE`: Affiliate deal.\n- `CUSTOM`: Custom reseller deal.\n- `DIRECT`: Direct non-affiliate deal with cashback.\n- `HANDSHAKE`: Handshake between buyer and seller with a form.\n- `NONE`: Discount is baked in.\n- `SELLER_INTEGRATION`: Seller integration flow.\n- `PROVISIONING`: Automated provisioning flow.\n- `PROVISIONING_MANUAL`: Manual provisioning flow.\n- `NACHO_PAY`: NachoPay flow. No pricing tiers; the seller charges the buyer on demand via `POST /payments`.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "NONE",
                  "DIRECT",
                  "AFFILIATE",
                  "CUSTOM",
                  "HANDSHAKE",
                  "SELLER_INTEGRATION",
                  "PROVISIONING",
                  "PROVISIONING_MANUAL",
                  "NACHO_PAY"
                ]
              },
              "example": [
                "DIRECT",
                "AFFILIATE"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated product list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "page": {
                      "type": "integer",
                      "example": 1
                    },
                    "take": {
                      "type": "integer",
                      "description": "Number of items per page",
                      "example": 10
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching products",
                      "example": 245
                    },
                    "products": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "integer",
                            "example": 42
                          },
                          "name": {
                            "type": "string",
                            "example": "Slack"
                          },
                          "logo": {
                            "type": "string",
                            "format": "uri",
                            "description": "Full URL to the product logo",
                            "example": "https://files.nachonacho.com/logo/slack.png"
                          },
                          "shortDescription": {
                            "type": "string",
                            "example": "Where work happens"
                          },
                          "sellerLink": {
                            "type": "string",
                            "format": "uri",
                            "example": "https://slack.com"
                          },
                          "productDescription": {
                            "type": "string"
                          },
                          "keyBenefits": {
                            "type": "string"
                          },
                          "pricing": {
                            "type": "string",
                            "example": "Starting at $7.25/month per user"
                          },
                          "relationshipType": {
                            "type": "string",
                            "enum": [
                              "NONE",
                              "DIRECT",
                              "AFFILIATE",
                              "CUSTOM",
                              "HANDSHAKE",
                              "SELLER_INTEGRATION",
                              "PROVISIONING",
                              "PROVISIONING_MANUAL",
                              "NACHO_PAY"
                            ],
                            "example": "DIRECT"
                          },
                          "offer": {
                            "type": "string",
                            "description": "Primary deal description",
                            "example": "20% off all plans"
                          },
                          "offer2": {
                            "type": "string",
                            "description": "Secondary deal description"
                          },
                          "eligibilityRequirements": {
                            "type": "string",
                            "description": "Requirements a company must meet to be eligible for the deal"
                          },
                          "estimateSavingText": {
                            "type": "string"
                          },
                          "estimatedSavingMax": {
                            "type": "number",
                            "format": "float"
                          },
                          "instructionsToRedeemDeal": {
                            "type": "string"
                          },
                          "features": {
                            "type": "string"
                          },
                          "instagramLink": {
                            "type": "string",
                            "format": "uri"
                          },
                          "linkedInLink": {
                            "type": "string",
                            "format": "uri"
                          },
                          "facebookLink": {
                            "type": "string",
                            "format": "uri"
                          },
                          "twitterLink": {
                            "type": "string",
                            "format": "uri"
                          },
                          "positionProducts": {
                            "type": "array",
                            "description": "Product category positions. The category object is returned as `categoryProduct`; the internal database field name `categorieProduct` is not exposed.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "description": "Position product ID.",
                                  "example": "clxx789ghi"
                                },
                                "categoryProduct": {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "type": "string",
                                      "example": "clxx123abc"
                                    },
                                    "name": {
                                      "type": "string",
                                      "example": "Marketing"
                                    },
                                    "level": {
                                      "type": "integer",
                                      "description": "Category hierarchy level.",
                                      "example": 1
                                    }
                                  }
                                }
                              }
                            }
                          },
                          "signupLink": {
                            "type": "string",
                            "format": "uri",
                            "description": "Affiliate signup link with NachoNacho tracking",
                            "example": "https://connect.nachonacho.com/signup-product/42?source=api"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter. `page` must be a positive integer and `relationshipType` must be an array of valid relationship type values.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid JWT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/products/{productId}": {
      "get": {
        "summary": "Get product details",
        "description": "Returns the full set of publicly visible fields for a single NachoNacho marketplace product by its ID.\n",
        "tags": [
          "Products"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "productId",
            "in": "path",
            "required": true,
            "description": "The product ID (from the `id` field returned by `GET /products`).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "example": 42
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Product details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "product": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 42
                        },
                        "name": {
                          "type": "string",
                          "example": "Slack"
                        },
                        "logo": {
                          "type": "string",
                          "format": "uri",
                          "description": "Full URL to the product logo",
                          "example": "https://files.nachonacho.com/logo/slack.png"
                        },
                        "shortDescription": {
                          "type": "string",
                          "example": "Where work happens"
                        },
                        "sellerLink": {
                          "type": "string",
                          "format": "uri",
                          "example": "https://slack.com"
                        },
                        "productDescription": {
                          "type": "string"
                        },
                        "keyBenefits": {
                          "type": "string"
                        },
                        "pricing": {
                          "type": "string",
                          "example": "Starting at $7.25/month per user"
                        },
                        "relationshipType": {
                          "type": "string",
                          "enum": [
                            "NONE",
                            "DIRECT",
                            "AFFILIATE",
                            "CUSTOM",
                            "HANDSHAKE",
                            "SELLER_INTEGRATION",
                            "PROVISIONING",
                            "PROVISIONING_MANUAL",
                            "NACHO_PAY"
                          ],
                          "example": "DIRECT"
                        },
                        "offer": {
                          "type": "string",
                          "description": "Primary deal description",
                          "example": "20% off all plans"
                        },
                        "offer2": {
                          "type": "string",
                          "description": "Secondary deal description"
                        },
                        "eligibilityRequirements": {
                          "type": "string",
                          "description": "Requirements a company must meet to be eligible for the deal"
                        },
                        "estimateSavingText": {
                          "type": "string"
                        },
                        "estimatedSavingMax": {
                          "type": "number",
                          "format": "float"
                        },
                        "instructionsToRedeemDeal": {
                          "type": "string"
                        },
                        "features": {
                          "type": "string"
                        },
                        "instagramLink": {
                          "type": "string",
                          "format": "uri"
                        },
                        "linkedInLink": {
                          "type": "string",
                          "format": "uri"
                        },
                        "facebookLink": {
                          "type": "string",
                          "format": "uri"
                        },
                        "twitterLink": {
                          "type": "string",
                          "format": "uri"
                        },
                        "positionProducts": {
                          "type": "array",
                          "description": "Product category positions. The category object is returned as `categoryProduct`; the internal database field name `categorieProduct` is not exposed.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Position product ID.",
                                "example": "clxx789ghi"
                              },
                              "categoryProduct": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "example": "clxx123abc"
                                  },
                                  "name": {
                                    "type": "string",
                                    "example": "Marketing"
                                  },
                                  "level": {
                                    "type": "integer",
                                    "description": "Category hierarchy level.",
                                    "example": 1
                                  }
                                }
                              }
                            }
                          }
                        },
                        "signupLink": {
                          "type": "string",
                          "format": "uri",
                          "description": "Affiliate signup link with NachoNacho tracking",
                          "example": "https://connect.nachonacho.com/signup-product/42?source=api"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid productId. Must be a positive integer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid JWT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Company must be a Tribe account and approved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Company not found or product not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/payments/{paymentId}/refund": {
      "post": {
        "summary": "Refund a NachoPay payment",
        "description": "Give a NachoPay charge back to the Buyer.\n\n**Refunds are always for the full amount.** There is no partial refund: the Buyer gets back exactly what they were charged, and the revshare fee and the payout recorded on the original payment are reversed with it.\n\nA payment can only be refunded once, and only while it is `succeeded`. A second call returns `409` with the id of the refund that already exists, so a retry is safe.\n\nThe refund is recorded on both objects in Stripe: the Refund carries `type: NACHO_PAY_REFUND` along with the product, subscription and reversed revenue share, and the original PaymentIntent is updated with `refunded`, `refundId`, `refundedAt`, `refundedFrom` and `revshareAmountReversed`. Both the Seller and the Buyer see the payment as refunded in their NachoNacho dashboard.\n\nMoney typically reaches the Buyer's card 5 to 10 business days later, depending on their bank.",
        "tags": [
          "NachoPay"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "paymentId",
            "in": "path",
            "required": true,
            "description": "The Stripe PaymentIntent ID returned by `POST /payments`.",
            "schema": {
              "type": "string",
              "example": "pi_3QabcDEfGhIjKlMn0PqRsTuV"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "description": "Optional note stored on the refund explaining why it was issued. Truncated to 350 characters.",
                    "example": "Charged by mistake"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Refund created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "refundId": {
                      "type": "string",
                      "example": "re_3QabcDEfGhIjKlMn0AbCdEfG"
                    },
                    "paymentId": {
                      "type": "string",
                      "example": "pi_3QabcDEfGhIjKlMn0PqRsTuV"
                    },
                    "subscriptionId": {
                      "type": "string",
                      "nullable": true,
                      "example": "cmmcoxge20001cnsppobu1anr"
                    },
                    "status": {
                      "type": "string",
                      "description": "Stripe refund status. See the [Stripe API documentation](https://stripe.com/docs/api/refunds/object).",
                      "example": "succeeded"
                    },
                    "amountRefunded": {
                      "type": "number",
                      "format": "float",
                      "description": "The full amount returned to the Buyer, in US dollars.",
                      "example": 80
                    },
                    "currency": {
                      "type": "string",
                      "example": "USD"
                    },
                    "revshareAmountReversed": {
                      "type": "number",
                      "format": "float",
                      "nullable": true,
                      "description": "The revshare fee that no longer applies because of this refund.",
                      "example": 30
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing paymentId, the payment is not a NachoPay payment, or it is not in a refundable state",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid JWT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Seller is not the owner of this product",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Payment not found or Seller company not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "This payment has already been refunded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "This payment has already been refunded"
                    },
                    "refundId": {
                      "type": "string",
                      "nullable": true,
                      "example": "re_3QabcDEfGhIjKlMn0AbCdEfG"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "JWT obtained from `POST /auth`"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "example": "Invalid or expired token"
          }
        }
      }
    }
  }
}
