{
 "openapi": "3.1.0",
 "info": {
  "title": "BobWork Email Warm-up API",
  "version": "1.0.0",
  "termsOfService": "https://emailwarmup.bobwork.ai/terms",
  "contact": {
   "name": "BobWork",
   "email": "info@bobwork.ai",
   "url": "https://emailwarmup.bobwork.ai"
  },
  "description": "Connect mailboxes, watch warm-up health and the ready-for-outbound gate, check SPF/DKIM/DMARC, run Outbound cold-email campaigns and pay, all without a browser. No key yet? An agent can sign up without a browser: POST https://app-emailwarmup.bobwork.ai/api/v1/signup/code with the person's email (a 6-digit code is emailed to them), then POST https://app-emailwarmup.bobwork.ai/api/v1/signup/verify with the nonce and code to get a bwk_ key. Guide: https://emailwarmup.bobwork.ai/llms-full.txt Free for 10 mailboxes per account; extra mailboxes $5/month per extra mailbox, $3 each from 10 extra, $2 each from 50 extra; Outbound $2 per 1,000 emails sent. The API itself is free. 120 requests per minute per key."
 },
 "externalDocs": {
  "description": "Agent guide (plain text)",
  "url": "https://emailwarmup.bobwork.ai/llms-full.txt"
 },
 "servers": [
  {
   "url": "https://app-emailwarmup.bobwork.ai/api/v1"
  }
 ],
 "security": [
  {
   "bearerAuth": []
  }
 ],
 "paths": {
  "/signup/code": {
   "post": {
    "tags": [
     "Sign up without a browser"
    ],
    "operationId": "post_signup_code",
    "summary": "No key needed",
    "description": "No key needed. {\"email\": \"you@company.com\"} emails a 6-digit code to that address (valid 10 minutes) and returns a nonce.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "email": {
          "type": "string",
          "format": "email",
          "description": "The person's email: the 6-digit code is sent here"
         }
        },
        "required": [
         "email"
        ]
       }
      }
     }
    },
    "security": []
   }
  },
  "/signup/verify": {
   "post": {
    "tags": [
     "Sign up without a browser"
    ],
    "operationId": "post_signup_verify",
    "summary": "No key needed",
    "description": "No key needed. {\"nonce\": \"…\", \"code\": \"123456\", \"key_name\": \"my agent\"} returns your API key (bwk_…, shown once). The account is created on first sign-in. Max 5 live keys per account.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "nonce": {
          "type": "string"
         },
         "code": {
          "type": "string",
          "description": "6 digits from the email"
         },
         "key_name": {
          "type": "string"
         }
        },
        "required": [
         "nonce",
         "code"
        ]
       }
      }
     }
    },
    "security": []
   }
  },
  "/billing": {
   "get": {
    "tags": [
     "Billing"
    ],
    "operationId": "get_billing",
    "summary": "Payment status: credit balance, extra-mailbox subscription (active, monthly cost), mailboxes vs free limit, ch",
    "description": "Payment status: credit balance, extra-mailbox subscription (active, monthly cost), mailboxes vs free limit, checkouts waiting for payment, prices. Poll it after handing over a checkout link; it confirms a paid checkout straight away.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/billing/checkout": {
   "post": {
    "tags": [
     "Billing"
    ],
    "operationId": "post_billing_checkout",
    "summary": "Stripe Checkout url for extra mailboxes beyond the free limit: {\"yearly\": false}",
    "description": "Stripe Checkout url for extra mailboxes beyond the free limit: {\"yearly\": false}. The account owner opens the url and pays; returns already: true if subscribed.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "yearly": {
          "type": "boolean"
         }
        },
        "required": []
       }
      }
     }
    }
   }
  },
  "/credits/checkout": {
   "post": {
    "tags": [
     "Billing"
    ],
    "operationId": "post_credits_checkout",
    "summary": "Stripe Checkout url to top up Outbound credits: {\"usd\": 10}",
    "description": "Stripe Checkout url to top up Outbound credits: {\"usd\": 10}. Packs: 5, 10, 25 or 100. The account owner opens the url and pays.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "usd": {
          "type": "integer",
          "enum": [
           5,
           10,
           25,
           100
          ]
         }
        },
        "required": [
         "usd"
        ]
       }
      }
     }
    }
   }
  },
  "/me": {
   "get": {
    "tags": [
     "Account"
    ],
    "operationId": "get_me",
    "summary": "Your email and credit balance",
    "description": "Your email and credit balance.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/usage": {
   "get": {
    "tags": [
     "Account"
    ],
    "operationId": "get_usage",
    "summary": "Free mailbox allowance (10, or 20 for accounts created before 27 October 2026, plus referral bonus), paid extr",
    "description": "Free mailbox allowance (10, or 20 for accounts created before 27 October 2026, plus referral bonus), paid extras, referral link and credits.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/account": {
   "get": {
    "tags": [
     "Account"
    ],
    "operationId": "get_account",
    "summary": "Pool mode (shared network or private pool) and your referral link",
    "description": "Pool mode (shared network or private pool) and your referral link.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "tags": [
     "Account"
    ],
    "operationId": "post_account",
    "summary": "Switch pool mode: {\"private_pool\": true}",
    "description": "Switch pool mode: {\"private_pool\": true}.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "private_pool": {
          "type": "boolean"
         }
        },
        "required": []
       }
      }
     }
    }
   }
  },
  "/credits": {
   "get": {
    "tags": [
     "Account"
    ],
    "operationId": "get_credits",
    "summary": "Prepaid credit balance, prices and recent charges",
    "description": "Prepaid credit balance, prices and recent charges.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/providers": {
   "get": {
    "tags": [
     "Connect mailboxes"
    ],
    "operationId": "get_providers",
    "summary": "IMAP/SMTP presets with hosts and ports (Gmail app password, Yahoo, iCloud, Zoho, Lark, SES, SendGrid, Mailgun,",
    "description": "IMAP/SMTP presets with hosts and ports (Gmail app password, Yahoo, iCloud, Zoho, Lark, SES, SendGrid, Mailgun, other).",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/mailboxes/imap": {
   "post": {
    "tags": [
     "Connect mailboxes"
    ],
    "operationId": "post_mailboxes_imap",
    "summary": "Connect any mailbox by IMAP + SMTP",
    "description": "Connect any mailbox by IMAP + SMTP. The login is tested before it is saved. Over the free limit it is saved paused and the answer has needs_billing:true plus how to pay; paying wakes it.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "email": {
          "type": "string",
          "description": "Mailbox address, e.g. sales@yourdomain.com"
         },
         "password": {
          "type": "string",
          "description": "Mailbox password or app password"
         },
         "preset": {
          "type": "string",
          "description": "e.g. gmail-imap, yahoo, icloud, zoho, lark, aws-ses, sendgrid, mailgun, other"
         },
         "name": {
          "type": "string",
          "description": "Display name on sent mail"
         },
         "host": {
          "type": "string",
          "description": "IMAP host (if no preset)"
         },
         "port": {
          "type": "integer"
         },
         "smtp_host": {
          "type": "string"
         },
         "smtp_port": {
          "type": "integer"
         },
         "user": {
          "type": "string",
          "description": "Login if not the email"
         },
         "smtp_user": {
          "type": "string",
          "description": "Relay platforms only (SES/SendGrid/Mailgun)"
         },
         "smtp_password": {
          "type": "string"
         }
        },
        "required": [
         "email",
         "password"
        ],
        "additionalProperties": false
       }
      }
     }
    }
   }
  },
  "/mailboxes/zoho": {
   "post": {
    "tags": [
     "Connect mailboxes"
    ],
    "operationId": "post_mailboxes_zoho",
    "summary": "Connect Zoho Mail through the Zoho API (free plan works) with a Self Client id, secret and code",
    "description": "Connect Zoho Mail through the Zoho API (free plan works) with a Self Client id, secret and code.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "email": {
          "type": "string",
          "description": "Mailbox address, e.g. sales@yourdomain.com"
         },
         "client_id": {
          "type": "string"
         },
         "client_secret": {
          "type": "string"
         },
         "code": {
          "type": "string",
          "description": "Self Client code (valid 10 minutes)"
         },
         "dc": {
          "type": "string",
          "description": "Zoho data centre: com, eu, in, com.au, jp, ca",
          "default": "com"
         },
         "name": {
          "type": "string"
         }
        },
        "required": [
         "email",
         "client_id",
         "client_secret",
         "code"
        ],
        "additionalProperties": false
       }
      }
     }
    }
   }
  },
  "/mailboxes/google/link": {
   "post": {
    "tags": [
     "Connect mailboxes"
    ],
    "operationId": "post_mailboxes_google_link",
    "summary": "Get a Google sign-in link for Gmail / Google Workspace",
    "description": "Get a Google sign-in link for Gmail / Google Workspace. Open it, allow, and the mailbox appears by itself.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "renew": {
          "type": "boolean",
          "description": "Make a fresh link"
         }
        },
        "required": [],
        "additionalProperties": false
       }
      }
     }
    }
   }
  },
  "/mailboxes": {
   "get": {
    "tags": [
     "Mailboxes"
    ],
    "operationId": "get_mailboxes",
    "summary": "Every mailbox: warm-up day, status, 7-day spam rate, today, last 7 days, daily target, ready for outbound",
    "description": "Every mailbox: warm-up day, status, 7-day spam rate, today, last 7 days, daily target, ready for outbound.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/mailboxes/{email}": {
   "get": {
    "tags": [
     "Mailboxes"
    ],
    "operationId": "get_mailboxes_email",
    "summary": "One mailbox",
    "description": "One mailbox.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "email",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   },
   "post": {
    "tags": [
     "Mailboxes"
    ],
    "operationId": "post_mailboxes_email",
    "summary": "Edit display name, daily cap (1-100) or time zone",
    "description": "Edit display name, daily cap (1-100) or time zone.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "email",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "daily_cap": {
          "type": [
           "integer",
           "null"
          ]
         },
         "timezone": {
          "type": "string"
         }
        },
        "required": [],
        "additionalProperties": false
       }
      }
     }
    }
   }
  },
  "/mailboxes/{email}/activity": {
   "get": {
    "tags": [
     "Mailboxes"
    ],
    "operationId": "get_mailboxes_email_activity",
    "summary": "The last 100 warm-up events: sent, received, replied, rescued from spam, errors",
    "description": "The last 100 warm-up events: sent, received, replied, rescued from spam, errors.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "email",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/mailboxes/{email}/pause": {
   "post": {
    "tags": [
     "Mailboxes"
    ],
    "operationId": "post_mailboxes_email_pause",
    "summary": "Pause warm-up",
    "description": "Pause warm-up.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "email",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/mailboxes/{email}/resume": {
   "post": {
    "tags": [
     "Mailboxes"
    ],
    "operationId": "post_mailboxes_email_resume",
    "summary": "Resume warm-up",
    "description": "Resume warm-up.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "email",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/mailboxes/{email}/test": {
   "post": {
    "tags": [
     "Mailboxes"
    ],
    "operationId": "post_mailboxes_email_test",
    "summary": "Sign in now and report whether the stored login still works",
    "description": "Sign in now and report whether the stored login still works.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "email",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/mailboxes/{email}/remove": {
   "post": {
    "tags": [
     "Mailboxes"
    ],
    "operationId": "post_mailboxes_email_remove",
    "summary": "Remove the mailbox and delete its stored login",
    "description": "Remove the mailbox and delete its stored login. Needs {\"confirm\": true}.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "email",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "confirm": {
          "type": "boolean"
         }
        },
        "required": [
         "confirm"
        ]
       }
      }
     }
    }
   }
  },
  "/stats": {
   "get": {
    "tags": [
     "Health"
    ],
    "operationId": "get_stats",
    "summary": "Totals across your mailboxes: today and last 7 days, active and ready counts",
    "description": "Totals across your mailboxes: today and last 7 days, active and ready counts.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/domains": {
   "get": {
    "tags": [
     "Health"
    ],
    "operationId": "get_domains",
    "summary": "SPF, DKIM selector, DMARC policy and MX for every connected domain",
    "description": "SPF, DKIM selector, DMARC policy and MX for every connected domain.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/tools/spf": {
   "get": {
    "tags": [
     "Health"
    ],
    "operationId": "get_tools_spf",
    "summary": "SPF lookup for any domain",
    "description": "SPF lookup for any domain.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "domain",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/tools/dkim": {
   "get": {
    "tags": [
     "Health"
    ],
    "operationId": "get_tools_dkim",
    "summary": "DKIM lookup: your selector, selectors seen in real mail, then 45 common ones",
    "description": "DKIM lookup: your selector, selectors seen in real mail, then 45 common ones.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "domain",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "selector",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/tools/dmarc": {
   "get": {
    "tags": [
     "Health"
    ],
    "operationId": "get_tools_dmarc",
    "summary": "DMARC record and policy for any domain",
    "description": "DMARC record and policy for any domain.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "domain",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/campaigns": {
   "get": {
    "tags": [
     "Outbound"
    ],
    "operationId": "get_campaigns",
    "summary": "Your campaigns with status and stats",
    "description": "Your campaigns with status and stats.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "tags": [
     "Outbound"
    ],
    "operationId": "post_campaigns",
    "summary": "Create a draft: name, emails [{subject, body, wait_days}], mailboxes, daily_limit",
    "description": "Create a draft: name, emails [{subject, body, wait_days}], mailboxes, daily_limit. Nothing is sent.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "emails": {
          "type": "array",
          "description": "1-4 emails in order",
          "items": {
           "type": "object",
           "properties": {
            "subject": {
             "type": "string"
            },
            "body": {
             "type": "string"
            },
            "wait_days": {
             "type": "integer",
             "description": "Days after the previous email (ignored for the first)"
            }
           },
           "required": [
            "body"
           ]
          }
         },
         "mailboxes": {
          "type": "array",
          "items": {
           "type": "string"
          }
         },
         "daily_limit": {
          "type": "integer",
          "description": "Per mailbox per day"
         }
        },
        "required": [
         "name",
         "emails"
        ],
        "additionalProperties": false
       }
      }
     }
    }
   }
  },
  "/campaigns/{id}": {
   "get": {
    "tags": [
     "Outbound"
    ],
    "operationId": "get_campaigns_id",
    "summary": "One campaign: emails, mailboxes, stats, time left",
    "description": "One campaign: emails, mailboxes, stats, time left.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   },
   "post": {
    "tags": [
     "Outbound"
    ],
    "operationId": "post_campaigns_id",
    "summary": "Edit a draft or paused campaign; fields you leave out are kept",
    "description": "Edit a draft or paused campaign; fields you leave out are kept.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "emails": {
          "type": "array",
          "items": {
           "type": "object"
          }
         },
         "mailboxes": {
          "type": "array",
          "items": {
           "type": "string"
          }
         },
         "daily_limit": {
          "type": "integer"
         }
        },
        "required": [],
        "additionalProperties": false
       }
      }
     }
    }
   }
  },
  "/campaigns/{id}/contacts": {
   "get": {
    "tags": [
     "Outbound"
    ],
    "operationId": "get_campaigns_id_contacts",
    "summary": "Contacts and where each is in the sequence (first 200)",
    "description": "Contacts and where each is in the sequence (first 200).",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   },
   "post": {
    "tags": [
     "Outbound"
    ],
    "operationId": "post_campaigns_id_contacts",
    "summary": "Add up to 1,000 contacts per call",
    "description": "Add up to 1,000 contacts per call. Duplicates and unsubscribed addresses are skipped.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "contacts": {
          "type": "array",
          "items": {
           "type": "object",
           "properties": {
            "email": {
             "type": "string"
            }
           },
           "required": [
            "email"
           ]
          }
         }
        },
        "required": [
         "contacts"
        ],
        "additionalProperties": false
       }
      }
     }
    }
   }
  },
  "/campaigns/{id}/start": {
   "post": {
    "tags": [
     "Outbound"
    ],
    "operationId": "post_campaigns_id_start",
    "summary": "Start or resume",
    "description": "Start or resume. Sends real email and uses credits ($2 per 1,000). Needs {\"accept_sending_rules\": true} the first time. If a picked mailbox is still warming it answers 400 with warming: true; send {\"accept_warming_risk\": true} only after the person agrees. Without credits it answers 402 with credits_required: true.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "accept_sending_rules": {
          "type": "boolean"
         },
         "accept_warming_risk": {
          "type": "boolean",
          "description": "The user agreed to send from mailboxes that have not finished warm-up"
         }
        },
        "required": [],
        "additionalProperties": false
       }
      }
     }
    }
   }
  },
  "/campaigns/{id}/pause": {
   "post": {
    "tags": [
     "Outbound"
    ],
    "operationId": "post_campaigns_id_pause",
    "summary": "Pause",
    "description": "Pause.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/shop/domains": {
   "get": {
    "tags": [
     "Domains & mailboxes"
    ],
    "operationId": "get_shop_domains",
    "summary": "Domains you bought here, their hosted mailboxes, renewal date and price, plus the IMAP/SMTP settings",
    "description": "Domains you bought here, their hosted mailboxes, renewal date and price, plus the IMAP/SMTP settings.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/shop/orders": {
   "get": {
    "tags": [
     "Domains & mailboxes"
    ],
    "operationId": "get_shop_orders",
    "summary": "Your domain orders and where each one is in setup",
    "description": "Your domain orders and where each one is in setup.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/shop/search": {
   "get": {
    "tags": [
     "Domains & mailboxes"
    ],
    "operationId": "get_shop_search",
    "summary": "Available lookalike domains with the price for the first term and the renewal",
    "description": "Available lookalike domains with the price for the first term and the renewal.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "q",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/shop/checkout": {
   "post": {
    "tags": [
     "Domains & mailboxes"
    ],
    "operationId": "post_shop_checkout",
    "summary": "Buy domains, with up to 3 mailboxes each: {\"domains\": [{\"domain\": \"getacme.com\", \"mailboxes\": [{\"local\": \"john",
    "description": "Buy domains, with up to 3 mailboxes each: {\"domains\": [{\"domain\": \"getacme.com\", \"mailboxes\": [{\"local\": \"john\", \"name\": \"John Tan\"}]}], \"accept_sending_rules\": true}. Returns a Stripe checkout url; setup starts once it is paid.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "domains": {
          "type": "array",
          "items": {
           "type": "object",
           "properties": {
            "domain": {
             "type": "string",
             "description": "Domain, e.g. yourdomain.com"
            },
            "mailboxes": {
             "type": "array",
             "items": {
              "type": "object",
              "properties": {
               "local": {
                "type": "string",
                "description": "Part before @, e.g. john"
               },
               "name": {
                "type": "string",
                "description": "Display name"
               }
              },
              "required": [
               "local"
              ]
             }
            }
           },
           "required": [
            "domain"
           ]
          }
         },
         "accept_sending_rules": {
          "type": "boolean"
         }
        },
        "required": [
         "domains",
         "accept_sending_rules"
        ],
        "additionalProperties": false
       }
      }
     }
    }
   }
  },
  "/shop/domains/{domain}/mailboxes": {
   "post": {
    "tags": [
     "Domains & mailboxes"
    ],
    "operationId": "post_shop_domains_domain_mailboxes",
    "summary": "Add mailboxes to a domain you own: {\"mailboxes\": [{\"local\": \"sarah\", \"name\": \"Sarah Lee\"}]}",
    "description": "Add mailboxes to a domain you own: {\"mailboxes\": [{\"local\": \"sarah\", \"name\": \"Sarah Lee\"}]}. Returns a Stripe checkout url ($3 per mailbox per month).",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "mailboxes": {
          "type": "array",
          "items": {
           "type": "object",
           "properties": {
            "local": {
             "type": "string",
             "description": "Part before @, e.g. john"
            },
            "name": {
             "type": "string",
             "description": "Display name"
            }
           },
           "required": [
            "local"
           ]
          }
         }
        },
        "required": [
         "mailboxes"
        ],
        "additionalProperties": false
       }
      }
     }
    }
   }
  },
  "/shop/mailboxes/{email}": {
   "get": {
    "tags": [
     "Domains & mailboxes"
    ],
    "operationId": "get_shop_mailboxes_email",
    "summary": "Login details (password, IMAP, SMTP) for one of your hosted mailboxes",
    "description": "Login details (password, IMAP, SMTP) for one of your hosted mailboxes.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "email",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/shop/domains/{domain}/dns": {
   "get": {
    "tags": [
     "Domains & mailboxes"
    ],
    "operationId": "get_shop_domains_domain_dns",
    "summary": "DNS records on a domain you own",
    "description": "DNS records on a domain you own.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   },
   "post": {
    "tags": [
     "Domains & mailboxes"
    ],
    "operationId": "post_shop_domains_domain_dns",
    "summary": "Add a record: {\"type\": \"CNAME\", \"name\": \"www\", \"content\": \"cname.vercel-dns.com\", \"ttl\": 600}",
    "description": "Add a record: {\"type\": \"CNAME\", \"name\": \"www\", \"content\": \"cname.vercel-dns.com\", \"ttl\": 600}. name is the subdomain, empty for the domain itself. Types: A, AAAA, CNAME, ALIAS, MX, TXT, CAA, SRV.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "type": {
          "type": "string"
         },
         "name": {
          "type": "string"
         },
         "content": {
          "type": "string"
         },
         "ttl": {
          "type": "integer"
         },
         "prio": {
          "type": "integer"
         }
        },
        "required": [
         "type",
         "content"
        ],
        "additionalProperties": false
       }
      }
     }
    }
   }
  },
  "/shop/domains/{domain}/dns/{id}/delete": {
   "post": {
    "tags": [
     "Domains & mailboxes"
    ],
    "operationId": "post_shop_domains_domain_dns_id_delete",
    "summary": "Delete a record",
    "description": "Delete a record. Deleting the MX, SPF, DKIM or DMARC records stops your mailboxes working.",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/Error"
     }
    },
    "parameters": [
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  }
 },
 "components": {
  "securitySchemes": {
   "bearerAuth": {
    "type": "http",
    "scheme": "bearer",
    "bearerFormat": "bwk_ personal API key",
    "description": "Create one with POST /signup/code + /signup/verify, or under API in the app."
   }
  },
  "responses": {
   "Error": {
    "description": "Error: 400 bad input, 401 bad key, 402 payment needed (the body says how to pay), 404, 409, 429 rate limit",
    "content": {
     "application/json": {
      "schema": {
       "type": "object",
       "properties": {
        "error": {
         "type": "string"
        }
       }
      }
     }
    }
   }
  }
 }
}