DaySurface

Overview

REST API overview, base URL, and quick start

The REST API exposes the same Gmail, PDF, and webhook tools your assistant gets over MCP as authenticated HTTP endpoints - one shared service registry behind all three transports, so behavior never drifts between them.

Reach for it when the caller is your own code rather than an agent: a cron job that triages overnight mail, a backend that files attachments, a script that drafts on your behalf.

Base URL

https://api.daysurface.com

The API shares one process with the MCP server, so the same deployment also answers MCP traffic at mcp.daysurface.com/mcp; api.daysurface.com is the canonical vanity host for REST. (daysurface.com is the product site, a separate service.)

Every example in these docs uses that host. Running the server yourself? Swap in your own deployment, or http://localhost:8000 when it is running locally via daysurface-serve.

Quick Example

Rank the ten threads that most need attention:

curl -X POST https://api.daysurface.com/api/v1/services/gmail_curate_inbox \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"limit": 10}'

Every tool follows the same shape - POST /api/v1/services/{tool_name} with the tool's input model as the body. The generated OpenAPI document lives at /openapi.json.

Discovery

The root path describes the deployment to whoever - or whatever - lands on it. No authentication required.

curl https://mcp.daysurface.com/
{
  "title": "DaySurface",
  "protocol": "mcp",
  "instructions": "This host serves the Model Context Protocol at https://mcp.daysurface.com/mcp ...",
  "mcp": {
    "url": "https://mcp.daysurface.com/mcp",
    "transport": "streamable-http",
    "authentication": { "required": true, "schemes": ["oauth2", "api_key"] },
    "tools": ["gmail_list_inbox", "gmail_compose", "..."]
  },
  "endpoints": { "mcp": "...", "health": "...", "server_card": "..." }
}

Browsers (Accept: text/html) get a small landing page with the same content.

Unknown paths return a 404 carrying the same endpoints map plus a did_you_mean hint, so a client probing a legacy transport path - /sse, /messages - is told where the endpoint actually lives:

{
  "error": {
    "code": "not_found",
    "message": "No handler for GET /sse. Did you mean https://mcp.daysurface.com/mcp?",
    "details": { "path": "/sse", "did_you_mean": "https://mcp.daysurface.com/mcp" },
    "request_id": "eee3ed63ac4b4651ab3911c47a21603e"
  },
  "endpoints": {
    "mcp": "https://mcp.daysurface.com/mcp",
    "health": "https://mcp.daysurface.com/health",
    "server_card": "https://mcp.daysurface.com/.well-known/mcp/server-card.json"
  }
}

endpoints sits beside error, carrying the same entries as the discovery response above. did_you_mean is present only when a known alias matches.

Health Check

No authentication required.

curl https://api.daysurface.com/health
{
  "status": "ok",
  "version": "0.1.1",
  "commit": "a1b2c3d",
  "timestamp": "2025-01-15T10:30:00+00:00",
  "components": {
    "api": { "status": "ok" },
    "database": { "status": "ok" },
    "redis": { "status": "not_configured" },
    "stripe": { "status": "ok" }
  }
}

Status is "ok" when all components are healthy, "degraded" if any have errors.

Next Steps

On this page