{
  "openapi": "3.1.0",
  "info": {
    "title": "Nexcade contact API",
    "version": "2.0.0",
    "description": "Submit demo requests for Nexcade. Show the human the final recipient and request details, then obtain explicit approval before submitting. A request to draft or prepare a message does not authorise submission. Nexcade uses the supplied details to respond. Privacy: https://nexcade.co.uk/privacy-policy/",
    "contact": {
      "name": "Nexcade",
      "email": "hello@nexcade.co.uk",
      "url": "https://nexcade.co.uk/contact/"
    }
  },
  "servers": [
    {
      "url": "https://nexcade.co.uk"
    }
  ],
  "externalDocs": {
    "description": "Human contact page",
    "url": "https://nexcade.co.uk/contact/"
  },
  "paths": {
    "/api/contact": {
      "post": {
        "summary": "Request a Nexcade demo",
        "description": "After explicit human approval, send a short request for Nexcade to discuss freight quoting, tenders, rate updates, bookings, or reporting. Include useful context such as preferred time windows, workflow details, or systems used.",
        "operationId": "requestWorkingSession",
        "tags": [
          "contact"
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Recommended for API clients. Use one new key per approved request and reuse it only for retries of that request. Resend keeps keys effective for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 200,
              "pattern": "^[A-Za-z0-9._:-]+$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WorkingSessionRequest"
              },
              "example": {
                "name": "Alex Morgan",
                "email": "alex@example.com",
                "company": "Example Forwarding",
                "workflow": "Quoting",
                "message": "We want to discuss quote turnaround for ocean imports and preferred times for a first call."
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/WorkingSessionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Request received",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid fields",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            }
          },
          "409": {
            "description": "The idempotency key is active or was used for different request details",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait when the matching request is still processing.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            }
          },
          "429": {
            "description": "Submission limit reached",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before another attempt.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            }
          },
          "500": {
            "description": "Contact delivery is temporarily unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            }
          },
          "502": {
            "description": "The delivery provider failed or returned an uncertain result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "WorkingSessionRequest": {
        "type": "object",
        "required": [
          "name",
          "email"
        ],
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "description": "Requester full name.",
            "minLength": 1,
            "maxLength": 160
          },
          "email": {
            "type": "string",
            "description": "Requester work email.",
            "format": "email",
            "minLength": 3,
            "maxLength": 220
          },
          "company": {
            "type": "string",
            "description": "Requester company.",
            "maxLength": 180
          },
          "workflow": {
            "type": "string",
            "description": "Main workflow they want to discuss.",
            "enum": [
              "Quoting",
              "Tenders",
              "Rate updates",
              "Bookings",
              "Reporting",
              "Something else"
            ]
          },
          "message": {
            "type": "string",
            "description": "Short context for the request. Include preferred time windows when useful.",
            "maxLength": 4000
          }
        }
      },
      "ContactResponse": {
        "type": "object",
        "required": [
          "ok",
          "message"
        ],
        "additionalProperties": false,
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "message": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "enum": [
              "delivery_failed",
              "delivery_unavailable",
              "idempotency_conflict",
              "invalid_form_token",
              "invalid_idempotency_key",
              "invalid_request",
              "rate_limited",
              "request_in_progress"
            ]
          }
        }
      }
    }
  }
}
