Last updated: 2026-05-01
Pulse is a pay-per-use audio-intelligence API operated by StudioSphere Inc.. You give Pulse a public audio URL or upload a file, and Pulse returns analytical metadata about the track — currently BPM (tempo), musical key, and a waveform-peaks visualization. Structure and chord analysis are coming later.
Pulse does not stream, host, distribute, share, or play back audio. It reads, measures, and reports non-expressive technical metadata. BPM and key are facts about the track. Waveform peaks are compressed amplitude samples for visualization, not playable audio and not enough to reconstruct the original recording.
This section is meant to be specific. We've validated each claim against the running code.
/var/lib/pulse/tmp/<job_id>.audio.<ext>) and deleted in a finally block before the worker returns — success, partial, or failure. Upload submissions land in a per-job tmpfs directory that's removed the same way.bpm.py, key.py, waveform.py) decode the file into memory, compute the result, and exit. No samples are written to durable storage.| What | Where | Why |
|---|---|---|
| API key + email + ToS metadata | pulse_accounts | Authentication and account recovery. Email may be used to send a billing receipt. |
| Banked-token balance | pulse_accounts.banked_tokens | Per-second pricing model. |
| Hash of the URL you submitted (API path) | pulse_usage_log.audio_url_hash | SHA-256 only — the URL itself is never written to this table. Used to dedupe identical submissions for billing-cache lookups. |
| The URL you submitted (Checkout path) | pulse_payment_jobs.audio_url | Stripe Checkout completes asynchronously; the worker needs a way to fetch the audio after payment confirmation. Stored as text on the payment record. Not the audio — only the link. |
| Hash of the audio bytes | pulse_analysis_cache.content_hash | SHA-256 of the file. Lets us return cached results when the same content is analyzed twice without re-running compute. |
| Analysis results | pulse_analysis_cache.result_json | BPM number, key string, waveform peaks (an array of compressed amplitude samples — visualization data, not the original audio and not sufficient to recreate it). Sample size: BPM ~70 bytes, waveform ~30 KB, key ~70 bytes. |
| Stripe checkout-session ID | stripe_checkout_session on pulse_payment_jobs, pulse_pack_purchases, pulse_usage_log | String like cs_live_a1... — an opaque handle Stripe assigned to your checkout. Pulse uses it to look up payment status. Not payment data. |
| Stripe payment-intent ID | stripe_payment_intent on the same tables | String like pi_3T... — an opaque handle for the underlying charge. Pulse uses it to issue refunds. Not payment data. |
| Stripe checkout URL | pulse_payment_jobs.stripe_checkout_url | The https://checkout.stripe.com/... URL Stripe gave us for the customer to pay at. We persist it so repeat /pay calls return the same URL instead of creating a new session. |
| Dollar amounts (integer cents) | amount_estimate_cents, amount_buffered_cents, amount_paid_cents, amount_refunded_cents, cost_usd | Just integers and a 3-letter currency code. The amount you paid, the amount we estimated, the amount we refunded. No card-specific fields. |
| Webhook event IDs | pulse_stripe_events | Idempotency table — stores event_id + event_type + timestamp. Prevents Stripe re-deliveries from double-charging or double-crediting. |
Two columns exist in the schema but are reserved and not currently written:
pulse_accounts.stripe_customer_id (Pulse doesn't create Stripe Customer objects today)
and pulse_payment_jobs.conversion_email (planned post-checkout follow-up flow that hasn't shipped).
We mention them only because someone reading the schema might notice them.
This is important enough to spell out in detail. The trust model is: your payment details flow to Stripe, never to Pulse.
stripe.checkout.sessions.create() with: payment mode, the line item (a price ID or amount + currency + product reference), and Pulse-specific metadata (job IDs, account IDs — no user-identifying fields). Pulse receives back a session ID and a checkout URL.checkout.stripe.com. From this point until you finish or cancel, you are on a page hosted by Stripe, not by Pulse. The card form, the form validation, the 3-D Secure challenge if any — all on Stripe's domain.checkout.session.completed event arrives at pulse.studiosphere.space/webhook/stripe, signature-verified. Pulse reads exactly these fields from the event: session.id, session.payment_intent, and session.metadata (the Pulse fields we set in step 1). We do not read customer_details (which would contain email/name/address), we do not read payment_method, we do not read any card-specific data.Refunds happen the same way in reverse: Pulse calls stripe.refunds.create({ payment_intent: pi_…, amount: cents }) with an opaque PaymentIntent ID. Stripe issues the refund to the original payment method without Pulse knowing what that payment method is.
The Stripe API is also used by Pulse for billing-display purposes only — fetching the public receipt URL Stripe hosts for the customer (pi.latest_charge.receipt_url), so we can show a "View on Stripe" link on the success page. The receipt is rendered by Stripe.
stripe SDK usage — it's about a dozen call sites in src/worker.js, src/routes/pay.js, src/routes/account/index.js, src/routes/webhook/stripe.js, and src/lib/cleanup.js. None of them touch a payment method.
/estimate so /pay and /analyze can reference the same quote. Auto-expires./status/<job_id> can serve repeat reads cheaply. Auto-expires.The MySQL database is backed up by our hosting provider (DreamHost). Backups inherit whatever's in the live tables — none of which contain audio. Backup retention follows the provider's rolling schedule (typically 30 days).
src/worker.js step 9. The schemas are in migrations/pulse_001_initial.sql through the latest. The result-cache TTL is in setJobResult() at src/worker.js. Email support@studiosphere.space if you want a deeper walk-through.
By using Pulse you confirm that:
/analyze, /upload, and /pay routes require explicit attestation of this — your client must send attestation.submitter_has_rights = true. In these terms, submitter_has_rights means you have the rights, permission, lawful access, or other legal basis described above. Your agent, assistant, DAW plugin, MCP client, or other integration may collect that confirmation for a single file or for the current user-requested folder, project, playlist, catalog selection, or batch. Lying about that voids these terms.If a claim, demand, loss, or expense arises from audio you submit or from your breach of these responsibilities, you agree to defend and indemnify StudioSphere Inc. and its officers, employees, contractors, and service providers to the fullest extent allowed by law.
Pricing is per-second of audio analyzed, multiplied by per-tool rates. The rate sheet at /tools is the source of truth.
/account/topup. Tokens never expire. If you refund a pack, banked tokens are debited proportionally — you can't double-spend a refunded purchase.Email support@studiosphere.space within 30 days of the charge. We'd much rather work it out directly than route through Stripe disputes.
To restate the point in the billing context: Pulse does not see your payment details — card number, CVV, expiration date, billing address, bank credentials, or any tokenized payment method — at any point in the payment flow. Stripe handles all of that on their hosted page. Pulse only sees Stripe-issued reference IDs (which we use to issue refunds) and the dollar amount of the charge. If you'd like the technical detail, see "How payment processing actually works" in §2 above.
You have two ways to remove your data:
If you want a copy of what we have on file (banked-token balance, recent jobs, recent purchases), email the same address.
Rights holders can also email support@studiosphere.space to request removal of cached analysis metadata associated with a specific audio file. Include enough information for us to identify the file or submission. Because Pulse does not store audio, we may need a copy or hash of the file to match the cache entry.
Pulse is provided "as is." We make our best effort at accurate analysis, uptime, and timely processing, but we don't warrant fitness for any specific purpose. Audio analysis is statistical; results can be off, especially on very short clips, distorted recordings, or content the model wasn't designed for.
StudioSphere Inc.'s aggregate liability under these terms is limited to the amount you paid Pulse in the twelve months preceding the claim.
If we change these terms in a way that materially affects your rights or our obligations, we'll update the "Last updated" date at the top and email a heads-up to any account with a registered address. Continued use after the update means you accept the new terms.
StudioSphere Inc. is based in Quebec, Canada. These terms are governed by the laws of Quebec and the federal laws of Canada that apply there. Disputes that can't be resolved by direct conversation are handled in Montreal courts.
Pulse is a service of StudioSphere. The broader StudioSphere platform terms — covering accounts, payments, and the listening-room product — are at studiosphere.space/terms. Where the two documents address the same topic, this Pulse-specific document controls for Pulse-related questions.
Questions, requests, or anything we should know: support@studiosphere.space.