{
  "openapi": "3.1.0",
  "info": {
    "title": "Privi Voice — 24/7 AI Voicemail & Call Screening",
    "version": "1.0.0",
    "description": "AI voicemail boxes: a dedicated US number answered by a conversational AI that takes messages, screens spam, and delivers transcripts + summaries to your webhook/email and the free /v1 API. Prepaid call credits; no refunds. New here? Human quickstart: https://privi-voice-gateway.fly.dev/start"
  },
  "servers": [
    {
      "url": "https://privi-voice-gateway.fly.dev"
    }
  ],
  "paths": {
    "/demo": {
      "post": {
        "operationId": "demo",
        "summary": "START HERE — a five-cent guided tour. Returns a LIVE demo phone number you can call right now to talk to Privi, plus a sample of the structured call record (transcript + AI summary) every answered call delivers, and current pricing. No inputs needed.",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$schema": "https://json-schema.org/draft/2020-12/schema",
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "What to do right now to hear Privi live"
                    },
                    "demo_number": {
                      "type": "string",
                      "description": "A live Privi Voice line — call it from any phone"
                    },
                    "what_you_get": {
                      "type": "string"
                    },
                    "sample_call_record": {
                      "type": "object",
                      "properties": {
                        "from": {
                          "type": "string"
                        },
                        "duration_s": {
                          "type": "number"
                        },
                        "action": {
                          "type": "string"
                        },
                        "summary": {
                          "type": "string"
                        },
                        "transcript": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "role": {
                                "type": "string"
                              },
                              "text": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "role",
                              "text"
                            ],
                            "additionalProperties": false
                          }
                        }
                      },
                      "required": [
                        "from",
                        "duration_s",
                        "action",
                        "summary",
                        "transcript"
                      ],
                      "additionalProperties": false,
                      "description": "The structured record every answered call produces"
                    },
                    "pricing": {
                      "type": "object",
                      "properties": {
                        "provision": {
                          "type": "string"
                        },
                        "topup": {
                          "type": "string"
                        },
                        "renew": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "provision",
                        "topup",
                        "renew"
                      ],
                      "additionalProperties": false
                    },
                    "next_step": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "message",
                    "demo_number",
                    "what_you_get",
                    "sample_call_record",
                    "pricing",
                    "next_step"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "402": {
            "description": "Payment required — the body carries an x402 accepts[] envelope (scheme \"exact\", network sui). Sign it and retry with the X-PAYMENT header."
          },
          "422": {
            "description": "Invalid request body — never charged"
          }
        },
        "x-payment-info": {
          "pricingMode": "fixed",
          "price": "0.05",
          "currency": "USDC",
          "protocols": [
            "mpp",
            "x402"
          ],
          "x402": {
            "scheme": "exact",
            "network": "sui:mainnet",
            "asset": "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
            "payTo": "0x279d0fea04ee22d98b9b9eea6326eb5972c25562e5aabc14f8ec5b176a8b759a"
          }
        }
      }
    },
    "/mailbox": {
      "post": {
        "operationId": "mailbox",
        "summary": "Provision an AI voicemail box: a dedicated US phone number (30 days of rental included) answered by a conversational AI that takes messages, screens spam, and notifies the owner. Includes 25 answered-call credits and a bearer token for the free /v1 read API (shown exactly once). Your notify target is validated before you are charged. Prepaid credits: 1 credit = 1 answered call (max 120s of AI conversation). Calls are conversational voicemail — the deliverable per call is a structured record (two-sided transcript, AI summary, caller number, outcome), pushed to your notify target and readable via the free /v1 API with your bearer token. No audio recordings. Records are kept for the life of the mailbox and for 30 days after retirement, then purged. All sales are final — x402 has no refund primitive; retiring a mailbox forfeits unused credits.",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$schema": "https://json-schema.org/draft/2020-12/schema",
                  "type": "object",
                  "properties": {
                    "mailbox_id": {
                      "type": "string"
                    },
                    "phone_number": {
                      "type": "string",
                      "description": "Your dedicated US number, E.164"
                    },
                    "token": {
                      "type": "string",
                      "description": "Bearer token for the free /v1 read API. Shown exactly once — store it now."
                    },
                    "credits": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Answered-call credits remaining"
                    },
                    "number_paid_through": {
                      "type": "string",
                      "description": "ISO date the number rental is paid through"
                    }
                  },
                  "required": [
                    "mailbox_id",
                    "phone_number",
                    "token",
                    "credits",
                    "number_paid_through"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "402": {
            "description": "Payment required — the body carries an x402 accepts[] envelope (scheme \"exact\", network sui). Sign it and retry with the X-PAYMENT header."
          },
          "422": {
            "description": "Invalid request body — never charged"
          }
        },
        "x-payment-info": {
          "pricingMode": "fixed",
          "price": "4.90",
          "currency": "USDC",
          "protocols": [
            "mpp",
            "x402"
          ],
          "x402": {
            "scheme": "exact",
            "network": "sui:mainnet",
            "asset": "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
            "payTo": "0x279d0fea04ee22d98b9b9eea6326eb5972c25562e5aabc14f8ec5b176a8b759a"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "type": "object",
                "properties": {
                  "owner_name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80,
                    "description": "Whose line this is — used in the AI's greeting"
                  },
                  "agent_name": {
                    "description": "Optional name the AI assistant goes by on calls (e.g. \"Ivy\"). Unnamed by default.",
                    "type": "string",
                    "maxLength": 60
                  },
                  "greeting_text": {
                    "description": "Custom opening line the AI speaks. Default: a generic assistant greeting.",
                    "type": "string",
                    "maxLength": 600
                  },
                  "notify": {
                    "type": "object",
                    "properties": {
                      "kind": {
                        "type": "string",
                        "enum": [
                          "webhook",
                          "email"
                        ],
                        "description": "How call notifications reach the owner"
                      },
                      "target": {
                        "type": "string",
                        "minLength": 3,
                        "maxLength": 500,
                        "description": "https:// URL (must answer a test POST with 2xx) or an email address. This MUST reach a human — it is where voicemail summaries and transcripts go."
                      }
                    },
                    "required": [
                      "kind",
                      "target"
                    ],
                    "additionalProperties": false,
                    "description": "Required notification channel; validated before you are charged."
                  },
                  "area_code": {
                    "description": "Preferred US area code; falls back to any US local if unavailable",
                    "type": "string",
                    "pattern": "^\\d{3}$"
                  }
                },
                "required": [
                  "owner_name",
                  "notify"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/mailbox/topup": {
      "post": {
        "operationId": "mailbox_topup",
        "summary": "Add 20 answered-call credits to an existing mailbox. Reactivates a mailbox that stopped answering because it ran out of credit. Anyone may pay for any mailbox_id.",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$schema": "https://json-schema.org/draft/2020-12/schema",
                  "type": "object",
                  "properties": {
                    "mailbox_id": {
                      "type": "string"
                    },
                    "credits": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "status": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "mailbox_id",
                    "credits",
                    "status"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "402": {
            "description": "Payment required — the body carries an x402 accepts[] envelope (scheme \"exact\", network sui). Sign it and retry with the X-PAYMENT header."
          },
          "422": {
            "description": "Invalid request body — never charged"
          }
        },
        "x-payment-info": {
          "pricingMode": "fixed",
          "price": "2.50",
          "currency": "USDC",
          "protocols": [
            "mpp",
            "x402"
          ],
          "x402": {
            "scheme": "exact",
            "network": "sui:mainnet",
            "asset": "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
            "payTo": "0x279d0fea04ee22d98b9b9eea6326eb5972c25562e5aabc14f8ec5b176a8b759a"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "type": "object",
                "properties": {
                  "mailbox_id": {
                    "type": "string",
                    "minLength": 1,
                    "description": "The mailbox_id returned by POST /mailbox"
                  }
                },
                "required": [
                  "mailbox_id"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/mailbox/renew": {
      "post": {
        "operationId": "mailbox_renew",
        "summary": "Extend a mailbox's phone-number rental by 30 days (stacks on the current paid-through date). Unrenewed numbers get a 7-day grace period after expiry, then are released and the mailbox retires.",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$schema": "https://json-schema.org/draft/2020-12/schema",
                  "type": "object",
                  "properties": {
                    "mailbox_id": {
                      "type": "string"
                    },
                    "number_paid_through": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "mailbox_id",
                    "number_paid_through"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "402": {
            "description": "Payment required — the body carries an x402 accepts[] envelope (scheme \"exact\", network sui). Sign it and retry with the X-PAYMENT header."
          },
          "422": {
            "description": "Invalid request body — never charged"
          }
        },
        "x-payment-info": {
          "pricingMode": "fixed",
          "price": "2.00",
          "currency": "USDC",
          "protocols": [
            "mpp",
            "x402"
          ],
          "x402": {
            "scheme": "exact",
            "network": "sui:mainnet",
            "asset": "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
            "payTo": "0x279d0fea04ee22d98b9b9eea6326eb5972c25562e5aabc14f8ec5b176a8b759a"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "type": "object",
                "properties": {
                  "mailbox_id": {
                    "type": "string",
                    "minLength": 1,
                    "description": "The mailbox_id returned by POST /mailbox"
                  }
                },
                "required": [
                  "mailbox_id"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/mailbox/recover": {
      "post": {
        "operationId": "mailbox_recover",
        "summary": "Utility endpoint — not a demo (see POST /demo for that). Rotate a mailbox's bearer token (recovery for a leaked/lost token). Only the wallet that originally paid for the mailbox may recover it — the small price exists so your wallet identity is payment-verified.",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$schema": "https://json-schema.org/draft/2020-12/schema",
                  "type": "object",
                  "properties": {
                    "mailbox_id": {
                      "type": "string"
                    },
                    "token": {
                      "type": "string",
                      "description": "Fresh bearer token; the old one is dead. Shown exactly once."
                    }
                  },
                  "required": [
                    "mailbox_id",
                    "token"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "402": {
            "description": "Payment required — the body carries an x402 accepts[] envelope (scheme \"exact\", network sui). Sign it and retry with the X-PAYMENT header."
          },
          "422": {
            "description": "Invalid request body — never charged"
          }
        },
        "x-payment-info": {
          "pricingMode": "fixed",
          "price": "0.10",
          "currency": "USDC",
          "protocols": [
            "mpp",
            "x402"
          ],
          "x402": {
            "scheme": "exact",
            "network": "sui:mainnet",
            "asset": "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
            "payTo": "0x279d0fea04ee22d98b9b9eea6326eb5972c25562e5aabc14f8ec5b176a8b759a"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "type": "object",
                "properties": {
                  "mailbox_id": {
                    "type": "string",
                    "minLength": 1,
                    "description": "The mailbox_id returned by POST /mailbox"
                  }
                },
                "required": [
                  "mailbox_id"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    }
  }
}