Humans as a Service for AI agents. Verify humans via phone 2FA, list skills, and let agents hire them with a clean API.
- Use Node.js 24.18.0 (the version in
.nvmrcand the production image)nvm use
- Install dependencies
npm ci
- Configure environment
cp .env.example .env.local
- Run dev server
npm run dev
- Lint:
npm run lint - Tests:
npm test - Watch mode:
npm run test:watch - Tests use
TEST_MONGO_URIorMONGO_URIif available; otherwise an in-memory MongoDB is started.
MONGODB_URI(required, orMONGO_URI)MONGO_URI(optional; used withMONGODB_DBifMONGODB_URIis not set)MONGODB_DB(optional, defaultshaasam)AUTH_SECRET(required in prod)SHAASAM_API_KEY(optional; if set, required for agent API calls)SHAASAM_PLATFORM_FEE_BPS(optional; platform fee in basis points)SHAASAM_ADMIN_KEY(required for admin moderation endpoints)REQUIRE_REVIEW(optional; if true, only approved humans appear in search)TWILIO_ACCOUNT_SID,TWILIO_AUTH_TOKEN,TWILIO_FROM(optional; SMS OTP)TWILIO_VERIFY_SERVICE_SID(optional; Twilio Verify SMS withoutTWILIO_FROM)STRIPE_SECRET_KEY(optional; payouts)STRIPE_WEBHOOK_SECRET(optional; Stripe webhook verification)STRIPE_CONNECT_RETURN_URL(optional)STRIPE_CONNECT_REFRESH_URL(optional)
GET /api/humans?skills=prompting,analysis&maxRate=120&availability=nowGET /api/humans?categories=research,debugging&sort=score&includeScores=trueGET /api/humans/:idPOST /api/requests{ "title": "Debug a flaky test", "description": "Repro steps + logs...", "skills": ["node", "playwright"], "budget": 150, "callbackUrl": "https://agent.example.com/webhooks/shaasam", "requester": { "name": "Agent-42", "org": "Acme AI" } }
POST /api/auth/start→{ phone }POST /api/auth/verify→{ phone, code }GET /api/profilePOST /api/profile
GET /api/humans/requests→{ available, mine }POST /api/humans/requests/:id→{ action: "accept" | "decline" | "start" | "complete" }
POST /api/payments/connect(requires human session)POST /api/payments/intent(agent -> hold funds with manual capture)Amount is in cents.{ "requestId": "optional-request-id", "humanId": "required-human-id", "amount": 15000, "currency": "usd" }POST /api/payments/capture(agent -> release funds){ "paymentId": "optional-db-id", "paymentIntentId": "pi_123" }POST /api/payments/cancel(agent -> cancel hold){ "paymentId": "optional-db-id", "paymentIntentId": "pi_123" }GET /api/payments/:id
POST /api/webhooks/stripe(Stripe event handler)
GET /api/admin/users?reviewStatus=pendingPOST /api/admin/users/:id/review{ "reviewStatus": "approved", "status": "active", "notes": "Looks good." }
- If Twilio is not configured, the OTP code is logged to the server in dev mode.
- If Stripe is not configured, the payout connect endpoint returns a 501.