Developers
For developers and AI agents.
What this site publishes for software, and how to send us an enquiry without the web form.
Machine-readable resources
The home page lists these in its Link response header, so an agent can find them from a single request.
| Resource | Address | Link relation |
|---|---|---|
| API catalog (RFC 9727) | /.well-known/api-catalog | api-catalog |
| OpenAPI 3.1 description of the enquiry API | /openapi.json | service-desc |
| This page | /developers | service-doc |
| Plain-text summary of the company for language models | /llms.txt | describedby |
| Agent skill for sending us an enquiry | /.well-known/agent-skills/index.json | |
| Authentication notes for agents (none needed) | /auth.md | |
| Sitemap | /sitemap.xml |
Pages as Markdown
Every page is also available as Markdown. Send Accept: text/markdown and the same address returns text/markdown instead of HTML, without the navigation, animations or form. Browsers are unaffected.
curl -H "Accept: text/markdown" https://shadowtracesolution.com/compliance
Our robots.txt allows search indexing, real-time AI answers and AI training (Content-Signal: search=yes, ai-input=yes, ai-train=yes).
Tools for agents in the browser
In browsers that support WebMCP (navigator.modelContext), each page registers two tools: get_page, which returns any page as Markdown, and send_enquiry, which sends the same enquiry as the contact form. Other browsers ignore them.
The enquiry API
One endpoint: POST https://shadowtracesolution.com/api/contact.php. It is the same endpoint the contact form uses, and an enquiry sent here is handled exactly like one sent through the form. It is stored, our office gets an email, and the sender gets a confirmation email with a reference number.
Only send an enquiry for a real person who asked you to contact us. The consent field confirms that they agree to our privacy policy, and the reply goes to their email address.
Request
Send JSON with Content-Type: application/json. Without application/json in Content-Type or Accept, the endpoint redirects to the contact page instead of answering in JSON, because that is how the plain HTML form works.
| Field | Required | Rules |
|---|---|---|
| name | Yes | Up to 120 characters |
| Yes | A valid address, up to 190 characters | |
| company | No | Up to 160 characters |
| topic | Yes | One of the values listed below |
| message | Yes | 10 to 6000 characters |
| consent | Yes | Exactly yes |
Topic values: Active security incident, Security testing, Digital forensics, DPDP / IT Act compliance, DDoS defense, Web development, Hosting, Privacy or data request, Something else. Use Active security incident only for an incident in progress, because those go to the front of the queue.
curl -X POST https://shadowtracesolution.com/api/contact.php \
-H "Content-Type: application/json" \
-d '{
"name": "Asha Rao",
"email": "[email protected]",
"company": "Example Pvt Ltd",
"topic": "DPDP / IT Act compliance",
"message": "We want a DPDP gap assessment for our customer app.",
"consent": "yes"
}'
Responses
200: stored and sent. The body is {"ok": true, "reference": "ST-20260924-7KQ2M", "ack": true, "days": 7}. ack says whether the confirmation email reached our mail server, and days is how many days we take to reply.
422: something needs fixing. errors maps each field to a message.
429: too many enquiries from your connection in the last hour. Wait before trying again.
502: the enquiry was stored under the returned reference, but our mail server did not respond. Do not send it again. We check stored enquiries daily.
405 for any method other than POST, and 500 if the form is switched off on our side.
The full schema is in openapi.json.