Docs

API and protocol reference for AI agents that need human input.

MTS exposes a minimal authenticated API plus an MCP server. Agents create surveys from JSON schema, humans answer at a hosted URL, and the agent retrieves structured results.

Authentication

Creator routes use bearer authentication with keys shaped like mts_sk_.... The raw key is only returned once when you call POST /api/keys.

curl -X POST https://www.humansurvey.co/api/keys \
  -H "Content-Type: application/json" \
  -d '{"name":"triage-agent"}'

Pass the key on authenticated requests:Authorization: Bearer mts_sk_...

Markdown Syntax

MTS has four semantic question types: choice, text, scale, and matrix. The parser turns them into a normalized survey schema.

Choice

**Q1. Which environment are you debugging?**

- ☐ Local
- ☐ Staging
- ☐ Production

Text

**Q2. What happened right before the error?**

> _______________________________________________

Scale

**Q3. How urgent is this issue?**

[scale 1-5 min-label="Low" max-label="Critical"]

Matrix

| # | Workflow Step | Status |
|---|---------------|--------|
| 1 | Install       | ☐Good ☐OK ☐Bad |
| 2 | Login         | ☐Good ☐OK ☐Bad |
| 3 | Reporting     | ☐Good ☐OK ☐Bad |

JSON Schema Input

The API accepts schema as the canonical input format. Send a SurveyInput object — the server validates question types, options, and conditional logic before storing the survey.

{
  "schema": {
    "title": "Incident Intake",
    "description": "Collect the missing facts before the agent responds.",
    "sections": [
      {
        "title": "Context",
        "questions": [
          {
            "type": "single_choice",
            "label": "Which environment is affected?",
            "required": true,
            "options": [
              { "label": "Local" },
              { "label": "Staging" },
              { "label": "Production" }
            ]
          },
          {
            "type": "scale",
            "label": "How urgent is this issue?",
            "required": true,
            "min": 1,
            "max": 5,
            "minLabel": "Low",
            "maxLabel": "Critical"
          }
        ]
      }
    ]
  }
}

The web demo lets you write plain text or Markdown and uses an LLM to translate it into schema before submitting — this mirrors what your agent would do.

API Reference

Machine-readable OpenAPI lives at /api/openapi.json. The cards below summarize the HTTP surface area.

POST /api/keys

Public

Create a new API key and return the raw secret once.

GET /api/keys

Bearer key

List metadata for the current key.

DELETE /api/keys/{id}

Bearer key

Revoke the current API key.

POST /api/surveys

Bearer key

Create a survey from JSON schema.

GET /api/surveys

Bearer key

List surveys owned by the current key.

GET /api/surveys/{id}

Public

Return survey metadata, schema, and lifecycle fields.

PATCH /api/surveys/{id}

Bearer key

Update status, max_responses, or expires_at.

POST /api/surveys/{id}/responses

Public

Submit a response payload.

GET /api/surveys/{id}/responses

Bearer key

Return aggregated question results and raw submissions.

Create survey

curl -X POST https://www.humansurvey.co/api/surveys \
  -H "Authorization: Bearer mts_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "schema": {
      "title": "Incident Intake",
      "sections": [{
        "questions": [
          {
            "type": "single_choice",
            "label": "Which environment is affected?",
            "required": true,
            "options": [
              { "label": "Local" },
              { "label": "Staging" },
              { "label": "Production" }
            ]
          }
        ]
      }]
    },
    "max_responses": 25,
    "expires_at": "2026-12-31T23:59:59.000Z"
  }'

Get results

curl https://www.humansurvey.co/api/surveys/svy_123/responses \
  -H "Authorization: Bearer mts_sk_..." 

Close survey

curl -X PATCH https://www.humansurvey.co/api/surveys/svy_123 \
  -H "Authorization: Bearer mts_sk_..." \
  -H "Content-Type: application/json" \
  -d '{"status":"closed"}'

MCP Tools

Claude Code and other MCP clients can call MTS directly through@mts/mcp-server.

{
  "mcpServers": {
    "survey": {
      "command": "npx",
      "args": ["-y", "@mts/mcp-server"],
      "env": { "MTS_API_KEY": "mts_sk_your_key_here" }
    }
  }
}

create_survey

Create a survey from Markdown or JSON schema and return the respondent URL.

get_results

Fetch structured results for a survey by survey_id.

list_surveys

List surveys owned by the configured API key.

close_survey

Close an open survey so it stops collecting responses.

create_survey({
  schema: {
    title: "Incident Intake",
    sections: [{
      questions: [
        { type: "single_choice", label: "Which environment?", required: true,
          options: [{ label: "Local" }, { label: "Staging" }, { label: "Production" }] },
        { type: "scale", label: "How urgent?", required: true, min: 1, max: 5,
          minLabel: "Low", maxLabel: "Critical" }
      ]
    }]
  }
})

get_results({
  survey_id: "svy_123"
})

close_survey({
  survey_id: "svy_123"
})

Conditional Logic

Use show if: blocks in Markdown or showIf in JSON schema to reveal follow-up questions only when the condition matches.

**Q1. Did the deploy finish?**

- ☐ Yes
- ☐ No

**Q2. Which step failed?**

> show if: Q1 = "No"

> _______________________________________________

Supported operators map to semantic checks:

  • = or eq for equality
  • != or neq for inequality
  • contains for multi-select membership
  • answered to check whether the earlier question has any answer