{
  "openapi": "3.1.0",
  "info": {
    "title": "Shadowtrace enquiry API",
    "version": "1.0.0",
    "description": "Sends an enquiry to Shadowtrace Solution Private Limited. This is the same endpoint the form at https://shadowtracesolution.com/contact uses, and submissions are handled exactly like form submissions: the enquiry is stored, the office is notified by email, and the sender receives a confirmation email with a reference number. Only submit on behalf of a real person who has asked you to contact Shadowtrace and who agrees to the privacy policy at https://shadowtracesolution.com/privacy.",
    "contact": {
      "name": "Shadowtrace Solution Private Limited",
      "url": "https://shadowtracesolution.com/contact"
    }
  },
  "externalDocs": {
    "description": "Human-readable documentation",
    "url": "https://shadowtracesolution.com/developers"
  },
  "servers": [
    {
      "url": "https://shadowtracesolution.com"
    }
  ],
  "paths": {
    "/api/contact.php": {
      "post": {
        "operationId": "sendEnquiry",
        "summary": "Send an enquiry",
        "description": "Send the body as JSON with Content-Type: application/json to get JSON responses. Without application/json in Content-Type or Accept, the endpoint answers with a 303 redirect to the contact page, which is how the plain HTML form works. Requests are rate-limited per connection per hour.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Enquiry"
              },
              "example": {
                "name": "Asha Rao",
                "email": "asha@example.com",
                "company": "Example Pvt Ltd",
                "topic": "DPDP / IT Act compliance",
                "message": "We process customer data for about 20,000 users and want a DPDP gap assessment.",
                "consent": "yes"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/Enquiry"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Enquiry stored and the office notified.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "reference"
                  ],
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "reference": {
                      "type": "string",
                      "pattern": "^ST-[0-9]{8}-[2-9A-HJ-NP-Z]{5}$",
                      "description": "Reference number, also sent to the sender by email."
                    },
                    "ack": {
                      "type": "boolean",
                      "description": "Whether the confirmation email to the sender was sent."
                    },
                    "days": {
                      "type": "integer",
                      "description": "Number of days within which Shadowtrace replies."
                    }
                  }
                }
              }
            }
          },
          "303": {
            "description": "Returned instead of JSON when neither Content-Type nor Accept contains application/json. Redirects to /contact with the result in the query string."
          },
          "405": {
            "description": "Any method other than POST.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "error"
                  ],
                  "properties": {
                    "ok": {
                      "const": false
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validation failed, or the submission arrived within 3 seconds of the ts value.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "required": [
                        "ok",
                        "errors"
                      ],
                      "properties": {
                        "ok": {
                          "const": false
                        },
                        "errors": {
                          "type": "object",
                          "description": "Field name to message.",
                          "additionalProperties": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    {
                      "type": "object",
                      "required": [
                        "ok",
                        "error"
                      ],
                      "properties": {
                        "ok": {
                          "const": false
                        },
                        "error": {
                          "type": "string"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Too many enquiries from this connection in the last hour.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "error"
                  ],
                  "properties": {
                    "ok": {
                      "const": false
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The form is not configured on the server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "error"
                  ],
                  "properties": {
                    "ok": {
                      "const": false
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "The enquiry was stored under the returned reference but the notification email failed. Do not send it again.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "reference",
                    "error"
                  ],
                  "properties": {
                    "ok": {
                      "const": false
                    },
                    "reference": {
                      "type": "string"
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Enquiry": {
        "type": "object",
        "required": [
          "name",
          "email",
          "topic",
          "message",
          "consent"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "description": "Sender's name."
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 190,
            "description": "Where the reply and the confirmation email go."
          },
          "company": {
            "type": "string",
            "maxLength": 160,
            "description": "Optional."
          },
          "topic": {
            "type": "string",
            "enum": [
              "Active security incident",
              "Security testing",
              "Digital forensics",
              "DPDP / IT Act compliance",
              "DDoS defense",
              "Web development",
              "Hosting",
              "Privacy or data request",
              "Something else"
            ],
            "description": "Use \"Active security incident\" only for an incident in progress; those are handled first."
          },
          "message": {
            "type": "string",
            "minLength": 10,
            "maxLength": 6000
          },
          "consent": {
            "type": "string",
            "const": "yes",
            "description": "Confirms the sender agrees to Shadowtrace using these details to reply, as described in the privacy policy."
          },
          "website": {
            "type": "string",
            "maxLength": 0,
            "description": "Must be empty or omitted."
          },
          "ts": {
            "type": "integer",
            "description": "Optional. Time the form was shown, in milliseconds since the Unix epoch. If given, submissions less than 3 seconds later are rejected."
          }
        }
      }
    }
  }
}
