Runtime invocation patterns
Calling Pulses
This guide focuses on request flow between vibes and Pulses, including same-origin /api calls, public endpoint access, platform-mediated grants, auth context, payload shape, and error handling expectations.
Invocation guidance for predictable vibe-to-Pulse communication.
Implementation focus
Apply this when wiring fetch calls from client code to Pulse routes or when stabilizing production request contracts.
Expected outcomes
- Call Pulse endpoints with consistent auth and error behavior.
- Design payloads that survive future handler evolution.
- Reduce production regressions from ad-hoc request semantics.
What's a Pulse Call?
A pulse is a serverless function that runs on Vibecodr's infrastructure. You can call pulses from your vibes (browser code), from other pulses, or via direct HTTP requests. This page explains how calls work and what stays private when a project is public or remixable.
If you author pulse files in src/server/ (or server/), treat that as the source folder convention. The request path is still /api/* or a pulse run URL, not /server/*.
From Vibes
Browser code calling your serverless functions.
From Pulses
Server-to-server calls between your functions.
Direct HTTP
Any HTTP client: curl, Postman, webhooks, etc.
Execution Openness And Source Privacy
Pulse execution stays social under the existing runtime model. A deployed pulse endpoint is public HTTP by default unless the owner's code rejects the request, adds validation, checks an API key, rate-limits, or otherwise closes the door.
Runtime use
Callers may use deployed pulse endpoints through the runtime path that already exists. Do not treat hidden source as access control.
Owner checks
Put auth, allowlists, signatures, validation, and rate limits in your pulse code when the behavior should not be open to arbitrary callers.
Private backend details
Backend source, private routes, logs, state details, and deployment details stay out of public docs, remix payloads, overlays, and source viewers.
Important: Hiding backend source and metadata makes the project easier to trust and remix honestly, but it does not secure sensitive behavior by itself. Your pulse should reject calls it should not serve.
Runtime Calls
Use runtime calls for execution, not for public metadata discovery. Studio can insert owner-side references for your own pulses, but those references are authoring conveniences, not public source sharing, route catalogs, or a promise that another creator's backend can be inspected.
Some runtime pulse URLs may still resolve even when they are absent from public discovery. Treat them as execution addresses only: they are intentionally absent from sitemap, canonical, SEO, source, remix, and public metadata surfaces.
URL formats
# Runtime execute URL
https://p.vxbe.space/v/pls_abc123def456
# API run endpoint
https://api.vibecodr.space/pulses/pls_abc123def456/run
Which URL should I use? Use the API run endpoint for small JSON payload calls from Vibecodr UI code. Use the runtime URL or same-origin combo /api/* routes when your pulse needs to read real HTTP headers such as Authorization, webhook signatures, or X-Api-Key. Use Vibecodr client helpers when the caller should carry platform runtime authorization.
Authoring references do not expose private backend source, private routes, schedules, logs, or deployment state.
Public projection surfaces may show only the boolean private-backend awareness signal where it helps users understand trust and remix behavior.
Runtime calls use the existing pulse execution lanes. Owners still secure sensitive behavior inside pulse code.
Studio shortcut: In the Studio editor, type /api/ to complete same-project backend routes from your visible source, or type env.secrets. inside pulse code to complete secret helper methods.
Calling Published Pulses
Deployed pulses are public HTTP endpoints by default. Runs count against the creator's plan, so sensitive or costly behavior should defend itself in code.
A deployed pulse endpoint is public HTTP by default; Pulse visibility protects source and operational metadata projection, not application-level access.
When you deploy from a Blueprint, Studio shows the original Pulse source and any setup checklist items. It does not run that handler in the browser preview pane; publish first, then test the deployed Pulse endpoint where request headers, secrets, connections, and runtime capabilities exist.
Important: Pulse source is owner-only, but deployed pulse endpoints are internet-facing. Vibecodr protects platform data boundaries and stored secrets, but you are responsible for application-level controls like authentication, signatures, validation, and per-key throttles if you don't want arbitrary callers to consume your monthly pulse runs.
From a browser or server
// Deployed pulses can be called without a platform grant unless your code rejects them.
const response = await fetch("https://api.vibecodr.space/pulses/pls_abc123def456/run", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ city: "San Francisco" })
});
const result = await response.json();
console.log(result);
Full HTTP call with your own auth header
// Use the runtime URL when your pulse code needs to inspect request headers.
const response = await fetch("https://p.vxbe.space/v/pls_abc123def456", {
method: "POST",
headers: {
"Authorization": "Bearer " + yourAppToken,
"X-Api-Key": publicClientKey,
"Content-Type": "application/json"
},
body: JSON.stringify({ type: "manual_run", payload: { city: "San Francisco" } })
});
const result = await response.json();
Example: app-level rate limiting with policy fetch
import { definePulse } from "@vibecodr/pulse";
export default definePulse(async (input, env) => {
const apiKey = env.request.headers.get("X-Api-Key");
if (!apiKey) return new Response("Missing API key", { status: 401 });
const gate = await env.fetch(env.pulse.RATE_LIMIT_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ apiKey, route: env.request.url }),
});
const decision = await gate.json();
if (!decision.allowed) return new Response("Too Many Requests", { status: 429 });
// ...do work...
return { processed: true, remaining: decision.remaining };
});
Payload shape: Send your payload directly or wrap it in payload. Vibecodr supplies the event envelope for you, and your pulse sees input only. For a manual run, env.event.type is manual_run. If you need a custom event type or context, use the product route or trigger flow that matches your app.
Request And Upload Limits
Pulse calls are meant for compact request data, webhooks, and app commands. They are not the file-upload path for large media, archives, or user-generated assets.
Signed-in helper calls
Signed-in helper-driven Pulse calls use a JSON envelope capped at 64 KiB. This keeps app commands small enough to parse safely.
Public runtime calls
Direct public runtime calls accept non-GET/HEAD bodies up to 1 MiB before Vibecodr rejects the request with 413 pulse.requestBodyTooLarge.
Large files
Use Vibecodr's storage, import, or image-upload surfaces for larger files, then pass a small id, URL, or metadata object to the Pulse.
Why this exists: Vibecodr still runs at the edge, but Pulse request-body caps are Vibecodr runtime boundaries. They protect creator plans, Worker memory, and dispatch admission before user code or provider calls run.
Authenticated And Programmatic Calls
A signed-in app call authenticates the caller to Vibecodr's platform boundary. A helper-authorized runtime call authenticates the Vibecodr execution lane while leaving Authorization available for your app's own token.
1
Signed-in app run
Use the signed-in app flow when the viewer's Vibecodr session decides whether a Pulse may run. The platform bearer proves the viewer to Vibecodr; it is not forwarded to your Pulse code as your app's own token.
2
External system
Use a webhook trigger, schedule, or product-provided caller token when a partner system needs narrow access to one Pulse. Keep the partner's token inside the request your Pulse validates.
Why grants? They are pulse-scoped and short-lived (around 90 seconds). They let Vibecodr verify the runtime call without taking over the standard Authorization header from your app protocol. Without helper-provided runtime authorization, the platform token authenticates only the Vibecodr caller and is not forwarded to pulse code.
Programmatic Caller Tokens
Runtime authorization tokens are needed when an external caller should be authorized by Vibecodr, or when you want to keep Authorization reserved for your own auth protocol while still making a helper-authorized runtime call:
90-Second TTL
Tokens expire quickly. Mint them right before use, don't cache them.
Pulse-Scoped
Each token is for one specific pulse. Can't reuse across pulses.
Signed by Vibecodr
Vibecodr verifies the token before execution.
Runtime-Scoped
Tokens authorize a narrow runtime call. They do not publish source or operational metadata.
Common Patterns
Helper function for app-owned Pulse calls
// Reusable helper for a combo app's own Pulse route
async function callPulse(route, payload) {
const response = await fetch(route, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
return response.json();
}
Calling external APIs from a pulse
// Inside a pulse handler
import { definePulse } from "@vibecodr/pulse";
export default definePulse(async (input, env) => {
const response = await env.fetch("https://api.weather.com/v1/forecast?city=NYC", {
auth: env.secrets.query("WEATHER_API_KEY", "apikey"),
});
return await response.json();
});
Using owner-side pulse references
// Studio can insert references for your own pulses.
// Public projection APIs do not disclose another creator's pulse source,
// routes, schemas, deployment state, or backend metadata.
const pulseRef = "my-weather-pulse";
// Use a pulse ID you own or a runtime URL that your app already has.
// Do not treat authoring references as a public metadata lookup contract.
Troubleshooting
401 Unauthorized
- Calling a pulse path whose code expects a signed-in session or custom token
- Supplying an invalid or expired programmatic authorization token
- Using a token issued for a different pulse ID
403 Forbidden
- Pulse code rejected the caller's identity or authorization details
- Pulse code rejected the request payload or method
- Pulse is disabled or quarantined
- Rate limit exceeded (120 requests/minute per user per pulse)
404 Not Found
- Pulse ID or runtime path doesn't exist
- Pulse isn't deployed (check the deployment status in Power ups)
- Typo in the runtime URL
413 Payload Too Large
- Signed-in helper request exceeded the
64 KiBJSON envelope - Direct runtime request body exceeded
1 MiB - Send a smaller payload or upload large files through the storage/import surfaces
429 Too Many Requests
- Burst rate limit exceeded (retry with backoff)
- Monthly pulse run limit exhausted (check your plan limits)
400 Bad Request (Project too large)
- Upload preflight rejected with
Estimated bundle too large - Reduce the project size or upgrade plan (see the Project size limit table in Storage and Quotas above)
Security Notes
Programmatic Authorization Best Practices
- Programmatic tokens are only needed for sessionless external systems
- Never store runtime authorization tokens - they expire in ~90 seconds
- Always mint a fresh token right before use
- Don't log authorization tokens (they're bearer tokens)
- Use HTTPS for all requests (Vibecodr enforces this)
Client call contract
Vibes call Pulses through same-origin /api routes. The client should send the smallest useful payload and expect structured responses with clear success and failure states.
Avoid coupling the client to provider-specific errors or internal platform details. The Pulse should translate backend concerns into a stable app-facing contract.
- Use relative /api paths from the vibe when possible.
- Send JSON payloads with explicit fields.
- Handle non-2xx responses in the client.
- Keep auth and validation rules in the Pulse handler for protected behavior.
const response = await fetch("/api/send-message", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ message })
});
const payload = await response.json();
if (!response.ok) {
throw new Error(payload.error ?? "Pulse call failed");
}
Request and upload limits
Pulse calls are for compact request data, webhooks, and app commands. They are not the large-file upload path for media, archives, or user-generated assets.
The API run endpoint JSON envelope is capped at 64 KiB. Direct public runtime calls through the Pulse runtime host accept non-GET/HEAD request bodies up to 1 MiB before returning 413 pulse.requestBodyTooLarge.
- Use storage, import, or image-upload surfaces for larger files.
- Pass a small id, URL, or metadata object to the Pulse after upload.
- Treat 413 responses as a request-shape issue, not a transient runtime failure.
Failure and auth behavior
A vibe should treat Pulse calls as networked backend calls, not as local helper functions. The request can fail, the payload can be invalid, the endpoint can reject the viewer, and the external provider behind the Pulse can be unavailable.
Protected behavior should fail closed in the Pulse and return an app-facing error that does not reveal secrets, internal grants, provider tokens, deployment details, or raw stack traces.
- Use session, signature, or owner-defined checks for restricted endpoint behavior.
- Return stable error codes or messages that the vibe can render safely.
- Avoid retry loops in the browser unless the operation is idempotent.
- Keep provider-specific diagnostics in owner-visible logs, not viewer-visible responses.
Example and read next
Example: a vibe submits form data to /api/send-message. Send explicit JSON, handle non-2xx responses, and let the Pulse translate provider failures into a stable app-facing error.
Use these related pages when you need the next layer of guidance. They point to the most likely follow-up tasks, not every page that happens to touch the same system.
- Read next: Pulse Routing
- Read next: Pulse SDK & Handlers
- Read next: Secrets & APIs
- Read next: How-To Guides