REST API Reference
Base URL: https://api.soft.house
A Authentication
/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": "..." }
} /api/auth/login Sign in with email and password. Rate limited: 5 attempts per 15 minutes.
Request Body
{
"email": "user@example.com",
"password": "securePassword123"
} /api/auth/google Initiate Google OAuth login flow. Redirects to Google consent screen.
/api/auth/logout Sign out and invalidate the current session. Requires authentication.
W Wishes
/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"
} /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
/api/wishes/:id Retrieve a specific wish by ID. Public wishes are accessible without authentication.
/api/wishes/:id Auth Required Update a wish. Only the owner can update. Re-triggers moderation if content changes.
/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.
/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"
} /api/ap2/cart-mandates Auth Required Create a cart mandate from an intent mandate with specific items and amounts.
/api/ap2/payment-mandates Auth Required Execute payment from a cart mandate via Google Pay.
/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.
/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}"
} /api/acp/checkout-sessions/:id/complete Complete payment processing. Uses idempotency keys to prevent double-charging (24-hour cache).
/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 successfulcheckout.session.expired- Session timed outpayment_intent.succeeded- Payment intent confirmedpayment_intent.payment_failed- Payment failed
E Error Codes
| Code | Status | Description |
|---|---|---|
| AUTH_REQUIRED | 401 | Missing or invalid authentication token |
| RATE_LIMIT_EXCEEDED | 429 | Too many requests |
| MODERATION_REJECTED | 422 | Wish content failed moderation |
| MANDATE_INVALID | 400 | Invalid mandate signature or data |
| BUDGET_EXCEEDED | 400 | Amount exceeds mandate budget cap |
| NONCE_INVALID | 400 | Replay attack detected (duplicate nonce) |
| IDEMPOTENCY_CONFLICT | 409 | Request 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}'