REST API Reference

Base URL: https://api.soft.house

A Authentication

POST /api/auth/signup

Create a new user account.

Request Body

{
  "email": "user@example.com",
  "password": "securePassword123",
  "name": "Jane Doe"
}

Response

{
  "success": true,
  "user": { "id": "uuid", "email": "user@example.com" },
  "session": { "access_token": "...", "refresh_token": "..." }
}
POST /api/auth/login

Sign in with email and password. Rate limited: 5 attempts per 15 minutes.

Request Body

{
  "email": "user@example.com",
  "password": "securePassword123"
}
GET /api/auth/google

Initiate Google OAuth login flow. Redirects to Google consent screen.

POST /api/auth/logout

Sign out and invalidate the current session. Requires authentication.

W Wishes

POST /api/wishes Auth Required

Create a new wish. Subject to AI moderation. Rate limited: 10 per hour.

Request Body

{
  "title": "Dog walker in San Francisco",
  "description": "Need someone to walk my golden retriever 3x/week",
  "category": "pet-care",
  "budget_max": 150,
  "budget_type": "fixed",
  "location_text": "San Francisco, CA",
  "urgency": "normal",
  "visibility": "public"
}

Response (201)

{
  "id": "uuid",
  "title": "Dog walker in San Francisco",
  "status": "pending_moderation",
  "protocol_type": "ap2",
  "moderation_score": 92,
  "created_at": "2025-11-08T12:00:00Z"
}
GET /api/wishes Auth Required

List the authenticated user's wishes.

Query Parameters

status - Filter by status (active, fulfilled, cancelled)

limit - Results per page (default: 20, max: 100)

offset - Pagination offset

GET /api/wishes/:id

Retrieve a specific wish by ID. Public wishes are accessible without authentication.

PUT /api/wishes/:id Auth Required

Update a wish. Only the owner can update. Re-triggers moderation if content changes.

GET /api/wishes/browse

Browse public wishes. Supports search, category filtering, and location-based results.

Query Parameters

q - Search query

category - Filter by category

lat, lng - Location coordinates

radius - Search radius in km

AP2 AP2 Protocol (Google)

Google Agent Payments Protocol endpoints for mandate-based payments via Google Pay.

POST /api/ap2/intent-mandates Auth Required

Create an intent mandate with budget cap. ECDSA-signed for tamper prevention.

Request Body

{
  "wish_id": "uuid",
  "max_amount": 150.00,
  "currency": "USD",
  "mandate_type": "intent"
}
POST /api/ap2/cart-mandates Auth Required

Create a cart mandate from an intent mandate with specific items and amounts.

POST /api/ap2/payment-mandates Auth Required

Execute payment from a cart mandate via Google Pay.

GET /api/ap2/mandates Auth Required

List, retrieve, and manage mandates. Supports filtering by type and status.

ACP ACP Protocol (Stripe)

OpenAI/Stripe Agentic Commerce Protocol endpoints for checkout session payments.

POST /api/acp/checkout-sessions Bearer Token

Create a Stripe checkout session for a wish. Uses SharedPaymentToken for scoped authorization.

Request Body

{
  "wish_id": "uuid",
  "amount": 140.00,
  "currency": "usd",
  "success_url": "https://wish.now/confirm-payment/{id}",
  "cancel_url": "https://wish.now/wishes/{id}"
}
POST /api/acp/checkout-sessions/:id/complete

Complete payment processing. Uses idempotency keys to prevent double-charging (24-hour cache).

POST /api/acp/payment-delegation Bearer Token

Create a SharedPaymentToken with merchant scope, max amount, and expiry for delegated payments.

H Webhooks

Stripe Webhooks

Stripe webhook events are verified using HMAC signatures. Configure your webhook endpoint in the Stripe dashboard.

Supported Events

  • checkout.session.completed - Payment successful
  • checkout.session.expired - Session timed out
  • payment_intent.succeeded - Payment intent confirmed
  • payment_intent.payment_failed - Payment failed

E Error Codes

Code Status Description
AUTH_REQUIRED401Missing or invalid authentication token
RATE_LIMIT_EXCEEDED429Too many requests
MODERATION_REJECTED422Wish content failed moderation
MANDATE_INVALID400Invalid mandate signature or data
BUDGET_EXCEEDED400Amount exceeds mandate budget cap
NONCE_INVALID400Replay attack detected (duplicate nonce)
IDEMPOTENCY_CONFLICT409Request already processed (returns cached response)

Code Examples

JavaScript (fetch)

const response = await fetch('https://api.soft.house/api/wishes', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${token}`
  },
  body: JSON.stringify({
    title: 'Dog walker in San Francisco',
    category: 'pet-care',
    budget_max: 150
  })
});
const wish = await response.json();

Python (requests)

import requests

response = requests.post(
    'https://api.soft.house/api/wishes',
    headers={'Authorization': f'Bearer {token}'},
    json={
        'title': 'Dog walker in San Francisco',
        'category': 'pet-care',
        'budget_max': 150
    }
)
wish = response.json()

cURL

curl -X POST https://api.soft.house/api/wishes \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"title":"Dog walker in SF","budget_max":150}'