Sounds API Reference
Integrate the Sounds platform into your mobile app. Authenticate users with their existing account, list and stream sounds via short-lived signed URLs, and manage favorites — all over plain HTTPS + JSON.
Every request is authenticated; audio is delivered through expiring signed URLs.
Edge-deployed endpoints with predictable response shapes and cursor pagination.
Tokens scope every query to the calling user — no manual ACL needed.
https://aparmita.aurahimalaya.org/api/v1Authentication
Every endpoint requires a bearer token. Mobile clients call our native auth endpoints (no third-party SDK or keys to bundle) and forward the returned access token.
1. Sign the user in
POST email + password to /auth/signin. You receive an access token (~1 hour) and a refresh token.
curl -X POST https://aparmita.aurahimalaya.org/api/v1/auth/signin \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"••••••••"}'
# => { "data": { "access_token": "...", "refresh_token": "...", "expires_in": 3600, ... } }2. Call the API
Send the access token in the Authorization header.
curl https://aparmita.aurahimalaya.org/api/v1/me \
-H "Authorization: Bearer $ACCESS_TOKEN"3. Refresh when it expires
On a 401, POST the refresh token to /auth/refresh and retry the original request with the new access token.
sk_live_) from the admin panel. Use those only for trusted backends — never ship one inside a mobile binary.Quickstart
List the first 20 sounds in the platform.
curl "https://aparmita.aurahimalaya.org/api/v1/sounds?limit=20" \
-H "Authorization: Bearer $ACCESS_TOKEN"Endpoints
All endpoints return JSON. Errors follow the shape { "error": { "code", "message" } }.
/api/v1/auth/signupSign up
Create a new user with email + password. Returns session tokens immediately, or `needs_email_confirmation: true` if email confirmation is required.
curl -X POST https://aparmita.aurahimalaya.org/api/v1/auth/signup \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"••••••••","full_name":"Asha P."}'{
"data": {
"access_token": "eyJhbGciOi…",
"refresh_token": "v1.MR…",
"token_type": "bearer",
"expires_at": 1782215000,
"expires_in": 3600,
"user": { "id": "1c4b…", "email": "user@example.com" }
}
}/api/v1/auth/signinSign in
Exchange email + password for an access token and refresh token.
curl -X POST https://aparmita.aurahimalaya.org/api/v1/auth/signin \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"••••••••"}'{
"data": {
"access_token": "eyJhbGciOi…",
"refresh_token": "v1.MR…",
"token_type": "bearer",
"expires_at": 1782215000,
"expires_in": 3600,
"user": { "id": "1c4b…", "email": "user@example.com" }
}
}/api/v1/auth/refreshRefresh access token
When a request returns 401, exchange the refresh token for a fresh access token and refresh token. Store the new refresh token — old ones are rotated.
curl -X POST https://aparmita.aurahimalaya.org/api/v1/auth/refresh \
-H "Content-Type: application/json" \
-d '{"refresh_token":"v1.MR…"}'{
"data": {
"access_token": "eyJhbGciOi…",
"refresh_token": "v1.NR…",
"token_type": "bearer",
"expires_at": 1782218600,
"expires_in": 3600
}
}/api/v1/auth/signoutSign out
Revokes the refresh token associated with the current access token. Delete locally stored tokens after a successful response.
curl -X POST https://aparmita.aurahimalaya.org/api/v1/auth/signout \
-H "Authorization: Bearer $ACCESS_TOKEN"{ "data": { "ok": true } }/api/v1/auth/oauth/googleSign in with Google (native)
Exchange a Google `id_token` (from the native iOS/Android Google Sign-In SDK) for an app session — no web redirect needed.
curl -X POST https://aparmita.aurahimalaya.org/api/v1/auth/oauth/google \
-H "Content-Type: application/json" \
-d '{"id_token":"<google_id_token>","nonce":"<optional_nonce>"}'{
"data": {
"access_token": "eyJhbGciOi…",
"refresh_token": "v1.MR…",
"token_type": "bearer",
"expires_at": 1782215000,
"expires_in": 3600,
"user": { "id": "1c4b…", "email": "user@example.com" }
}
}/api/v1/soundsList sounds
Returns active sounds, ordered by sort order then most recent. Supports cursor pagination.
| Name | Type | Description |
|---|---|---|
| category | string | Filter by intention slug (parent or sub-intention). |
| include_children | boolean | When `category` is a parent intention, also include sounds tagged with its sub-intentions. |
| featured | boolean | Only return featured (true) or non-featured (false) sounds. |
| search | string | Case-insensitive match against the sound title. |
| limit | integer (1–100) | Page size. Defaults to 50. |
| cursor | ISO8601 string | Pass `next_cursor` from the previous response to fetch the next page. |
curl "https://aparmita.aurahimalaya.org/api/v1/sounds?category=meditation&limit=20" \
-H "Authorization: Bearer $ACCESS_TOKEN"{
"data": [
{
"id": "9e7a…",
"title": "Heart Bowl — F#",
"category": "meditation",
"frequency_hz": 369,
"duration_sec": 412,
"cover_image_url": "covers/abc.jpg",
"is_featured": true,
"play_count": 1284,
"created_at": "2026-06-01T12:34:56Z"
}
],
"next_cursor": "2026-05-30T08:11:02Z"
}/api/v1/sounds/{id}Get sound + signed audio URL
Returns the full sound record along with a short-lived signed URL for streaming. The audio URL expires after 5 minutes — request it again right before playback.
| Name | Type | Description |
|---|---|---|
| id* | uuid | Sound ID. |
curl "https://aparmita.aurahimalaya.org/api/v1/sounds/9e7a…" \
-H "Authorization: Bearer $ACCESS_TOKEN"{
"data": {
"id": "9e7a…",
"title": "Heart Bowl — F#",
"audio_url": "https://…r2.cloudflarestorage.com/audio/abc.mp3?X-Amz-Signature=…",
"audio_url_expires_in": 300,
"cover_image_url": "https://…/covers/abc.jpg?X-Amz-Signature=…",
"duration_sec": 412,
"frequency_hz": 369
}
}/api/v1/sounds/{id}/playTrack a play
Atomically increments the sound's global play counter. Call this once when playback starts.
| Name | Type | Description |
|---|---|---|
| id* | uuid | Sound ID. |
curl -X POST "https://aparmita.aurahimalaya.org/api/v1/sounds/9e7a…/play" \
-H "Authorization: Bearer $ACCESS_TOKEN"{ "data": { "id": "9e7a…", "play_count": 1285 } }/api/v1/favoritesList favorites
Returns the calling user's favorite sounds, newest first, with a compact sound preview.
curl "https://aparmita.aurahimalaya.org/api/v1/favorites" \
-H "Authorization: Bearer $ACCESS_TOKEN"{
"data": [
{
"sound_id": "9e7a…",
"created_at": "2026-06-20T09:12:00Z",
"sounds": {
"id": "9e7a…",
"title": "Heart Bowl — F#",
"category": "meditation",
"cover_image_url": "covers/abc.jpg",
"duration_sec": 412
}
}
]
}/api/v1/favoritesAdd a favorite
Idempotent. Adds a sound to the user's favorites; calling it again is a no-op.
| Name | Type | Description |
|---|---|---|
| sound_id* | uuid | Sound to favorite. |
curl -X POST "https://aparmita.aurahimalaya.org/api/v1/favorites" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"sound_id":"9e7a…"}'{ "data": { "ok": true } }/api/v1/favorites/{soundId}Remove a favorite
Removes a sound from the user's favorites.
| Name | Type | Description |
|---|---|---|
| soundId* | uuid | Sound to unfavorite. |
curl -X DELETE "https://aparmita.aurahimalaya.org/api/v1/favorites/9e7a…" \
-H "Authorization: Bearer $ACCESS_TOKEN"{ "data": { "ok": true } }/api/v1/meCurrent user
Returns the calling user's profile. Useful for validating a token after sign-in.
curl "https://aparmita.aurahimalaya.org/api/v1/me" -H "Authorization: Bearer $ACCESS_TOKEN"{
"data": {
"id": "1c4b…",
"email": "user@example.com",
"full_name": "Asha P.",
"avatar_url": null
},
"auth_via": "jwt"
}/api/v1/me/customerCurrent customer
Returns the calling end-user's customer record (profile data for the mobile app, including signup source — `email`, `google`, or `apple` — and marketing preferences).
curl "https://aparmita.aurahimalaya.org/api/v1/me/customer" \
-H "Authorization: Bearer $ACCESS_TOKEN"{
"data": {
"id": "1c4b…",
"email": "user@example.com",
"full_name": "Asha P.",
"avatar_url": null,
"phone": null,
"provider": "google",
"source": "google",
"locale": "en-US",
"country": "IN",
"marketing_opt_in": false,
"is_active": true,
"last_seen_at": null,
"created_at": "2026-06-20T09:12:00Z",
"updated_at": "2026-06-20T09:12:00Z"
},
"auth_via": "jwt"
}/api/v1/me/customerUpdate current customer
Update editable fields on the caller's customer record. Email and provider are managed by auth and cannot be changed here.
| Name | Type | Description |
|---|---|---|
| full_name | string | null | Display name. |
| avatar_url | string | null | Public avatar URL. |
| phone | string | null | Contact phone number. |
| locale | string | null | BCP-47 locale, e.g. `en-US`. |
| country | string | null | ISO 3166-1 alpha-2 country code. |
| marketing_opt_in | boolean | Opt in/out of marketing emails. |
curl -X PATCH "https://aparmita.aurahimalaya.org/api/v1/me/customer" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"full_name":"Asha P.","country":"IN","marketing_opt_in":true}'{
"data": {
"id": "1c4b…",
"full_name": "Asha P.",
"country": "IN",
"marketing_opt_in": true,
"updated_at": "2026-06-23T10:00:00Z"
}
}/api/v1/homeHomepage sections
Returns active homepage sections in display order, each with its resolved list of sounds (manual picks or rule-based).
curl "https://aparmita.aurahimalaya.org/api/v1/home" \
-H "Authorization: Bearer $ACCESS_TOKEN"{
"sections": [
{
"id": "7d1c…",
"slug": "editors-picks",
"title": "Editor's Picks",
"mode": "manual",
"rule_type": null,
"rule_value": null,
"rule_include_children": false,
"sounds": [
{
"id": "9e7a…",
"title": "Heart Bowl — F#",
"category": "meditation",
"cover_image_url": "covers/abc.jpg",
"duration_sec": 412
}
]
}
]
}/api/v1/categoriesIntentions (categories)
Returns active intentions in display order, each with its nested sub-intentions. Auth is optional — guests may call it without a token.
curl "https://aparmita.aurahimalaya.org/api/v1/categories"{
"data": [
{
"id": "3a1f…",
"name": "Sleep",
"slug": "sleep",
"description": "Wind down and drift off.",
"sort_order": 1,
"children": [
{
"id": "b92c…",
"name": "Falling asleep",
"slug": "falling-asleep",
"description": null,
"sort_order": 0
}
]
}
]
}Errors
All errors share a consistent envelope.
{ "error": { "code": "unauthorized", "message": "Invalid or expired access token." } }| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Body or query parameters failed validation. |
| 401 | unauthorized | Missing, invalid, or expired token. |
| 404 | not_found | The requested resource doesn't exist or is not visible to you. |
| 429 | rate_limited | Too many requests — back off and retry after the reset window. |
| 500 | server_error | Something went wrong on our side. Safe to retry with backoff. |
Rate limits
Default limit: 60 requests per minute per user. Every response includes:
X-RateLimit-Limit— the window's allowed requestsX-RateLimit-Remaining— requests left in this windowX-RateLimit-Reset— Unix timestamp when the window resets
Exceeded limits return 429 rate_limited. Implement exponential backoff (start at 1s, double up to 30s).
Security best practices
- Use user JWTs in mobile apps. Never bundle an
sk_live_key in a binary you ship to end users. - Store tokens securely. iOS Keychain / Android Keystore — not plain SharedPreferences or UserDefaults.
- Refresh signed audio URLs. They expire after 5 minutes. Re-request right before playback; don't cache.
- Rotate compromised keys immediately from Admin → API Keys. Revocation takes effect within a few seconds.
- HTTPS only. The API rejects plain HTTP. Pin certificates for high-assurance deployments.
Changelog
- 2026-06-23 · v1.0 — Initial release. Sounds, favorites, play tracking, and current-user endpoints.