# API Usage Guide

This document shows how to use the REST API for status page management.

## Authentication

All API requests require a Bearer token in the Authorization header. No token yet? See [Agent Signup](https://ups.dev/docs/agent-signup.md) for the bootstrap flow.

```bash
Authorization: Bearer ups_live_abc123_xyz789
```

## Rate Limiting

- 60 requests per minute per API token
- Returns 429 status when exceeded
- Rate limit resets every minute

## API Endpoints

### 1. List Status Pages
```http
GET /api/v1/status_pages
Authorization: Bearer <token>
```

Response:
```json
{
  "status_pages": [
    {
      "id": 1,
      "name": "Production Status",
      "slug": "production",
      "description": "Status of our production services",
      "url": "https://status.example.com/production",
      "timezone": "UTC",
      "components_count": 3,
      "incidents_count": 5,
      "overall_status": "operational",
      "created_at": "2024-01-01T00:00:00Z",
      "updated_at": "2024-01-01T00:00:00Z"
    }
  ]
}
```

### 2. Get Status Page Details
```http
GET /api/v1/status_pages/:id
Authorization: Bearer <token>
```

Response includes components and recent incidents.

### 3. Update Component Status (Money Endpoint 💰)
```http
PATCH /api/v1/status_pages/:status_page_id/components/:id
Authorization: Bearer <token>
Content-Type: application/json

{
  "component": {
    "status": "major_outage"
  }
}
```

**Component Status Values:**
- `operational` - All systems operational
- `degraded_performance` - Reduced performance
- `partial_outage` - Some functionality unavailable
- `major_outage` - Service completely down
- `under_maintenance` - Planned maintenance

Response:
```json
{
  "component": {
    "id": 1,
    "name": "API Server",
    "status": "major_outage",
    "status_text": "Major outage",
    "uptime_percentage": 0.0,
    "last_updated_at": "2024-01-01T12:00:00Z"
  },
  "message": "Component status changed from Operational to Major outage"
}
```

### 4. Create Incident
```http
POST /api/v1/status_pages/:status_page_id/incidents
Authorization: Bearer <token>
Content-Type: application/json

{
  "incident": {
    "title": "Database Connection Issues",
    "description": "Users may experience slow response times",
    "status": "investigating",
    "impact": "major",
    "component_ids": [1, 2]
  }
}
```

### 5. Update Incident
```http
PATCH /api/v1/status_pages/:status_page_id/incidents/:id
Authorization: Bearer <token>
Content-Type: application/json

{
  "incident": {
    "status": "resolved",
    "update_message": "The issue has been resolved and all services are operational."
  }
}
```

**Incident Status Values:**
- `investigating` - We are investigating the issue
- `identified` - Issue has been identified
- `monitoring` - Fix implemented, monitoring situation
- `resolved` - Issue completely resolved

## Example: CI/CD Pipeline Integration

```bash
#!/bin/bash
# Deploy script that updates component status

API_TOKEN="ups_live_abc123_xyz789"
STATUS_PAGE_ID="1"
COMPONENT_ID="2"

# Set component to maintenance
curl -X PATCH "https://ups.dev/api/v1/status_pages/${STATUS_PAGE_ID}/components/${COMPONENT_ID}" \
  -H "Authorization: Bearer ${API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"component":{"status":"under_maintenance"}}'

# Deploy application...
deploy_app.sh

# Set component back to operational
curl -X PATCH "https://ups.dev/api/v1/status_pages/${STATUS_PAGE_ID}/components/${COMPONENT_ID}" \
  -H "Authorization: Bearer ${API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"component":{"status":"operational"}}'
```

## Error Handling

All endpoints return consistent error responses:

```json
{
  "error": "Validation failed",
  "details": ["Name can't be blank"]
}
```

Common status codes:
- `200` - Success
- `201` - Created
- `400` - Bad Request
- `401` - Unauthorized (invalid token)
- `404` - Not Found
- `422` - Validation Error
- `429` - Rate Limited
## Custom Domains (Pro and Business)

Serve a status page at your own hostname. The flow is designed for agents: every
response says what to do next, and the only human step is adding a DNS record.

```bash
# 1. Set the host (402 on the free plan, with upgrade instructions)
curl -X PUT https://ups.dev/api/v1/status_pages/1/custom_domain \
  -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
  -d '{"custom_domain":"status.example.com"}'
# → "dns": [{"type":"CNAME","name":"status.example.com","value":"custom.ups.dev"},
#           {"type":"TXT","name":"_ups-challenge.status.example.com","value":"ups-domain-verification=..."}]

# 2. Add both records at your DNS provider (apex domains: ALIAS/ANAME or A records matching custom.ups.dev).
#    The TXT record proves you control the zone; keep it in place.

# 3. Verify; both checks passing turns on routing and automatic TLS for the host
curl -X POST https://ups.dev/api/v1/status_pages/1/custom_domain/verify \
  -H "Authorization: Bearer YOUR_TOKEN"
# → "check": {"verified": true, ...}, "custom_domain": {"public_url": "https://status.example.com/"}
```

`GET` the same resource for current state, `DELETE` to remove it. Full mechanics in
CUSTOM_DOMAINS.md.

## Billing (agent-driven)

Paid plans are bought with a Stripe **shared payment token**: the customer's agent
platform (Stripe Link, for example) issues a token scoped to ups.dev's Stripe
profile with an amount cap the customer approved. No checkout page, no card
details through ups.dev.

```bash
# 1. Plans, amounts, and the seller profile to scope the token to
curl -H "Authorization: Bearer YOUR_TOKEN" https://ups.dev/api/v1/billing
# → "plans":[{"id":"pro_monthly","amount":1000,"currency":"usd",...}],
#   "payment":{"method":"shared_payment_token","seller":{"network_business_profile":"profile_..."},"agent_instructions":[...]}

# 2. Obtain an spt_ for that amount (see payment.agent_instructions), then subscribe
curl -X POST https://ups.dev/api/v1/billing/subscription \
  -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"plan":"pro_monthly","shared_payment_token":"spt_..."}'
# → 201 {"subscription":{"plan":"pro_monthly","status":"active","current_period_end":...,"renewal":{...}},"payment":{"id":"pi_...","receipt_url":...}}
```

Errors (`error.code`): `invalid_plan`, `token_required`, `token_rejected` (422),
`payment_declined` / `payment_incomplete` (402), `already_subscribed` (409). Plan
limits, including custom domains, take effect as soon as the 201 comes back.
One-time tokens cover one period; renew by POSTing a fresh one in its last 7 days
(recurring tokens renew automatically).
Full onboarding walk-through: [AGENT_SIGNUP.md](https://ups.dev/docs/agent-signup.md).
