{
  "openapi": "3.1.0",
  "info": {
    "title": "abuenoben public contact API",
    "version": "1.0.0",
    "summary": "Human-verified project brief intake for abuenoben.",
    "description": "This contract documents the public contact form used by abuenoben. It is not an autonomous bulk-submission API. Production requests require an allowed Origin and a valid Cloudflare Turnstile token issued by the public website. Agents must not fabricate tokens, bypass anti-spam controls or include credentials and secrets. API revisions are identified by the API-Version response header. Breaking replacements will be published as a new dated version and any retirement will be announced with Deprecation and Sunset headers before removal.",
    "x-versioning-policy": {
      "strategy": "API-Version header",
      "current": "2026-08-29",
      "deprecation": "Deprecation and Sunset headers are published before a breaking version is retired."
    }
  },
  "servers": [
    {
      "url": "https://abuenoben.com",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Contact",
      "description": "Human-reviewed project brief intake."
    }
  ],
  "paths": {
    "/api/contact": {
      "post": {
        "tags": [
          "Contact"
        ],
        "operationId": "submitContactBrief",
        "summary": "Submit a human-verified project brief",
        "description": "Captures a project brief after origin validation, payload validation, spam checks, Turnstile verification and rate limiting. A browser must obtain the Turnstile token from the public contact form before this operation is called.",
        "x-human-verification-required": true,
        "parameters": [
          {
            "$ref": "#/components/parameters/ApiVersion"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID retained when retrying the same brief. Reusing it with different content is rejected.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactBrief"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The brief is durably queued for Research OS. Delivery is retried if the private CRM is unavailable.",
            "headers": {
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactSuccess"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "502": {
            "$ref": "#/components/responses/CaptureUnavailable"
          },
          "default": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "ApiVersion": {
        "name": "API-Version",
        "in": "header",
        "required": false,
        "description": "Optional dated contract version. Omit it or send 2026-08-29 for the current contact contract.",
        "schema": {
          "type": "string",
          "const": "2026-08-29",
          "default": "2026-08-29"
        }
      }
    },
    "headers": {
      "ApiVersion": {
        "description": "Dated version of the contact contract used for this response.",
        "schema": {
          "type": "string",
          "const": "2026-08-29"
        }
      },
      "RateLimit": {
        "description": "Current remaining quota and effective reset window.",
        "schema": {
          "type": "string"
        }
      },
      "RateLimitPolicy": {
        "description": "Contact-form quota policies.",
        "schema": {
          "type": "string"
        }
      },
      "RetryAfter": {
        "description": "Seconds to wait before retrying a throttled request.",
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      }
    },
    "schemas": {
      "ContactBrief": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "email",
          "organizationType",
          "message",
          "consent",
          "honeypot",
          "sourceUrl",
          "startedAt",
          "turnstileToken"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 120
          },
          "company": {
            "type": "string",
            "maxLength": 160
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 160
          },
          "website": {
            "type": "string",
            "maxLength": 200
          },
          "organizationType": {
            "type": "string",
            "enum": [
              "agency",
              "brand",
              "startup",
              "other"
            ]
          },
          "projectType": {
            "type": "string",
            "enum": [
              "web",
              "mobile",
              "integration",
              "support",
              "other"
            ]
          },
          "collaborationType": {
            "type": "string",
            "enum": [
              "hours",
              "project",
              "support"
            ]
          },
          "budgetRange": {
            "type": "string",
            "enum": [
              "lt5k",
              "5k-10k",
              "10k-25k",
              "25kplus",
              "unknown"
            ]
          },
          "timeline": {
            "type": "string",
            "enum": [
              "urgent",
              "2-4w",
              "1-2m",
              "flexible"
            ]
          },
          "message": {
            "type": "string",
            "minLength": 20,
            "maxLength": 3000
          },
          "consent": {
            "type": "boolean",
            "const": true,
            "description": "Confirms review of the privacy policy."
          },
          "adsMeasurementConsent": {
            "type": "boolean",
            "default": false
          },
          "adsMeasurementConsentVersion": {
            "type": "string",
            "const": "google-ads-measurement-v1-2026-07-24"
          },
          "honeypot": {
            "type": "string",
            "maxLength": 0
          },
          "sourceUrl": {
            "type": "string",
            "maxLength": 500
          },
          "referrer": {
            "type": "string",
            "maxLength": 500
          },
          "startedAt": {
            "type": "integer",
            "minimum": 1
          },
          "utmSource": {
            "type": "string",
            "maxLength": 200
          },
          "utmMedium": {
            "type": "string",
            "maxLength": 200
          },
          "utmCampaign": {
            "type": "string",
            "maxLength": 200
          },
          "attribution": {
            "$ref": "#/components/schemas/Attribution"
          },
          "turnstileToken": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000,
            "description": "Short-lived Cloudflare Turnstile token issued by the public form."
          }
        }
      },
      "Attribution": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "firstLandingPath",
          "formPath",
          "referrerDomain",
          "capturedAt",
          "leadIntent",
          "utmSource",
          "utmMedium",
          "utmCampaign",
          "utmId",
          "utmSourcePlatform",
          "utmTerm",
          "utmContent",
          "campaignId",
          "adGroupId",
          "adId",
          "gclid",
          "gbraid",
          "wbraid",
          "analyticsConsent",
          "advertisingConsent",
          "consentVersion"
        ],
        "properties": {
          "schemaVersion": {
            "type": "integer",
            "const": 1
          },
          "firstLandingPath": {
            "type": "string",
            "maxLength": 500
          },
          "formPath": {
            "type": "string",
            "maxLength": 500
          },
          "referrerDomain": {
            "type": "string",
            "maxLength": 500
          },
          "capturedAt": {
            "type": "string",
            "format": "date-time"
          },
          "leadIntent": {
            "type": "string",
            "enum": [
              "general",
              "agency_support",
              "white_label_web",
              "api_crm",
              "mobile_app_development",
              "mobile_maintenance",
              "android_specialist",
              "verifactu",
              "einvoice_b2b",
              "accessibility"
            ]
          },
          "utmSource": {
            "type": "string",
            "maxLength": 200
          },
          "utmMedium": {
            "type": "string",
            "maxLength": 200
          },
          "utmCampaign": {
            "type": "string",
            "maxLength": 200
          },
          "utmId": {
            "type": "string",
            "maxLength": 200
          },
          "utmSourcePlatform": {
            "type": "string",
            "maxLength": 200
          },
          "utmTerm": {
            "type": "string",
            "maxLength": 200
          },
          "utmContent": {
            "type": "string",
            "maxLength": 200
          },
          "campaignId": {
            "type": "string",
            "maxLength": 200
          },
          "adGroupId": {
            "type": "string",
            "maxLength": 200
          },
          "adId": {
            "type": "string",
            "maxLength": 200
          },
          "gclid": {
            "type": "string",
            "maxLength": 512
          },
          "gbraid": {
            "type": "string",
            "maxLength": 512
          },
          "wbraid": {
            "type": "string",
            "maxLength": 512
          },
          "analyticsConsent": {
            "type": "boolean"
          },
          "advertisingConsent": {
            "type": "boolean"
          },
          "consentVersion": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "clickIdExpiresAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ContactSuccess": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "success",
          "message",
          "requestId",
          "hubspotStatus",
          "stage"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "message": {
            "type": "string"
          },
          "requestId": {
            "type": "string",
            "format": "uuid"
          },
          "hubspotStatus": {
            "type": "string",
            "enum": [
              "synced",
              "skipped",
              "error"
            ],
            "deprecated": true
          },
          "stage": {
            "type": "string",
            "const": "complete"
          },
          "crmStatus": {
            "type": "string",
            "enum": [
              "queued"
            ]
          }
        }
      },
      "ErrorDetail": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "code",
          "message",
          "resolution"
        ],
        "properties": {
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "resolution": {
            "type": "string"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "instance",
          "success",
          "code",
          "message",
          "resolution",
          "error"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri-reference"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer",
            "minimum": 400,
            "maximum": 599
          },
          "detail": {
            "type": "string"
          },
          "instance": {
            "type": "string",
            "format": "uri-reference"
          },
          "success": {
            "type": "boolean",
            "const": false
          },
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "resolution": {
            "type": "string"
          },
          "error": {
            "$ref": "#/components/schemas/ErrorDetail"
          },
          "requestId": {
            "type": "string",
            "format": "uuid"
          },
          "stage": {
            "type": "string"
          },
          "errors": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "hubspotStatus": {
            "type": "object",
            "description": "Diagnostic delivery status returned only when all capture channels fail.",
            "additionalProperties": true
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Unsupported API version, invalid JSON or field validation failure.",
        "headers": {
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Origin, spam or human-verification rejection.",
        "headers": {
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "MethodNotAllowed": {
        "description": "Only POST and OPTIONS are accepted.",
        "headers": {
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "PayloadTooLarge": {
        "description": "The request body exceeds 16 KiB.",
        "headers": {
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "UnsupportedMediaType": {
        "description": "The request must use application/json.",
        "headers": {
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "The IP or email quota is exhausted.",
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          },
          "RateLimit": {
            "$ref": "#/components/headers/RateLimit"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          },
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "ServerError": {
        "description": "Unexpected processing failure.",
        "headers": {
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "CaptureUnavailable": {
        "description": "Neither CRM nor internal email could capture the brief.",
        "headers": {
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    }
  }
}
