{
  "openapi": "3.0.3",
  "info": {
    "title": "Conure API",
    "version": "1.0.0",
    "description": "Deterministic security APIs: bot detection and email risk scoring. Every verdict is a documented rule with a stated weight — no model, no black box. The Free plan includes 1,000 checks per calendar month. A check is refunded on any non-2xx response, so failures cost nothing.",
    "contact": {
      "name": "Conure API",
      "url": "https://conureapi.com/docs"
    }
  },
  "servers": [
    {
      "url": "https://conureapi.com",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Metered",
      "description": "One check against your monthly quota per successful call."
    },
    {
      "name": "Account",
      "description": "Authenticated, never metered."
    }
  ],
  "paths": {
    "/v1/bot-check": {
      "post": {
        "operationId": "botCheck",
        "summary": "Bot check",
        "description": "POST the visitor IP, and optionally their User-Agent and headers, to /v1/bot-check with your API key as a bearer token. The response comes back with is_bot, a 0-100 risk_score and the named reasons behind it, so you can log the decision and defend it later.\n\nScores an IP and User-Agent pair. A risk score above 50 sets is_bot. The IP half is deterministic: a merged range table over published datacenter CIDRs, with no heuristics.",
        "tags": [
          "Metered"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ip": {
                    "type": "string",
                    "description": "IPv4 address of the client."
                  },
                  "user_agent": {
                    "type": "string",
                    "description": "Raw User-Agent header. Absent or empty is itself a signal."
                  },
                  "headers": {
                    "type": "object",
                    "description": "Request headers, up to 64 entries. Missing browser headers add risk."
                  }
                },
                "required": [
                  "ip"
                ]
              },
              "example": {
                "ip": "52.1.2.3",
                "user_agent": "curl/8.4.0"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A verdict was produced.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "is_bot": true,
                  "risk_score": 100,
                  "reasons": [
                    "datacenter_ip",
                    "missing_sec_ch_ua",
                    "missing_accept_language",
                    "missing_sec_fetch_site",
                    "known_bot_user_agent"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Malformed body, or a field failed validation. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or revoked API key. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Monthly quota exceeded. Upgrade to continue. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Honour Retry-After. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Our fault. Quote the request_id. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "A dependency is unavailable. Retry shortly. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/email-check": {
      "post": {
        "operationId": "emailCheck",
        "summary": "Email risk",
        "description": "POST the address to /v1/email-check with your API key as a bearer token. You get is_risky, a 0-100 risk_score, the named reasons, and mx_status from a live DNS lookup. Use it on signup to reject throwaway mailboxes before they reach your database.\n\nScores an address on syntax, role-account shape, disposable-domain membership, free-provider status and a live MX lookup. A risk score above 40 sets is_risky. A DNS failure scores zero rather than inventing a verdict.",
        "tags": [
          "Metered"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "description": "Address to score. Maximum 254 characters."
                  }
                },
                "required": [
                  "email"
                ]
              },
              "example": {
                "email": "admin@mailinator.com"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A verdict was produced.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "email": "admin@mailinator.com",
                  "is_risky": true,
                  "is_role": true,
                  "is_disposable": true,
                  "is_free_provider": false,
                  "has_mx": true,
                  "mx_status": "has_mx",
                  "risk_score": 90,
                  "reasons": [
                    "role_account",
                    "disposable_domain"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Malformed body, or a field failed validation. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or revoked API key. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Monthly quota exceeded. Upgrade to continue. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Honour Retry-After. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Our fault. Quote the request_id. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "A dependency is unavailable. Retry shortly. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "usage",
        "summary": "Usage",
        "description": "GET /v1/usage with your API key as a bearer token. It returns the current period, your plan, how many checks you have made this month and how many the plan still allows. This call is never metered, so monitoring it costs nothing.\n\nPlan and monthly usage for the key. Authenticated but never metered: checking what is left is free.",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "A verdict was produced.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "period": "2026-08",
                  "plan": "free",
                  "plan_name": "Free",
                  "used": 412,
                  "quota": 1000,
                  "quota_display": "1,000",
                  "remaining": 588,
                  "percent_used": 41,
                  "signals": [
                    "email",
                    "ip"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Malformed body, or a field failed validation. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or revoked API key. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Honour Retry-After. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Our fault. Quote the request_id. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "A dependency is unavailable. Retry shortly. Does not count against your quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Your API key, created in the dashboard and shown exactly once."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Human-readable failure."
          },
          "request_id": {
            "type": "string",
            "description": "Quote this if you contact support."
          },
          "details": {
            "type": "array",
            "description": "Field-level problems, when the failure was validation.",
            "items": {
              "type": "object",
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        },
        "required": [
          "error"
        ]
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    }
  ]
}
