Hosting
We can run your flows, campaigns and Text flows for you, so you need no server for them. Add hosting: 'hcc' to a definition, and hcc deploy bundles it and uploads it to us. The code is the same either way: a flow file works whether we run it or you do.
Hosted code runs in test and in live. Live needs a live plan in good standing: see Plans.
Run a definition on HCC
import { defineCallFlow } from '@hccrun/sdk';
export const hello = defineCallFlow('hello', { hosting: 'hcc' }, function* (c) {
yield* c.say('Thanks for calling. Goodbye.');
yield* c.hangup();
});defineCampaign and defineTextFlow take the same option. Left out, it's 'self': your server runs it, as before.
- Mix them in one project. Each definition runs where it says. If any of them is self-hosted,
hcc.config.tsstill needs anendpointfor those. A project that's all hosted needs noendpointand no server. - Where it runs is part of the version. Adding or removing
hosting: 'hcc'makes a new version. A call in progress stays where it started, and new calls go to the new home. See During a deploy. hcc devruns everything on your machine, hosted definitions too, while it's attached. See Local development.
Deploy
npx hcc deploy # to test
npx hcc deploy --live # to live and testhcc deploy bundles only the hosted definitions, with every package they import, into .hcc/hosted/test.js (live.js with --live). That file is a build output: keep it out of git. It uploads the bundle and checks that it loads, then registers your definitions. If the upload fails, nothing changes: the code already running keeps running.
- A package that won't bundle fails the deploy, and says which.
hcc deploy --checkalso compares the hosted code running with a fresh build.- A call in progress keeps its version: old versions are in the new bundle too.
--liveuploads to both environments, each with its own secrets, and activates neither unless both loaded.--no-testuploads to live only.- Without a live plan in good standing, a live upload fails with the reason, and nothing changes.
Secrets
Hosted code reads its settings from secrets. They're per environment (live code reads live's, test code test's), and write-only: once set, nobody can read a value back, in the dashboard or the API. Set them with hcc secrets, or in the dashboard under Settings › Hosted code.
echo -n "$STRIPE_KEY" | npx hcc secrets set STRIPE_KEY
npx hcc secrets set STRIPE_KEY # or type it at a prompt that doesn't echo
npx hcc secrets list # names and when each was set, never values
npx hcc secrets delete STRIPE_KEY
npx hcc secrets set STRIPE_KEY --live # live's, with a live keysetnever takes the value as an argument, so it stays out of your shell history.- Live secrets take
--liveand a live key withsecrets:write. In the dashboard, only owners and admins can set or delete them; developers can set test's. - Read a secret with
c.env.STRIPE_KEYin a flow, orctx.env.STRIPE_KEYin a tool. - Values you name with
env('NAME'), such as an agent id, come from secrets too, so set one for each.hcc deploywarns about anyenv('NAME')in hosted code with no secret by that name. - A change reaches running code at once, with no deploy. If it can't,
hcc secretssays it arrives with the next deploy. - We add our own:
HCC_API_KEYin live andHCC_TEST_API_KEYin test, a key with the scopes a flow needs (calls, leads, Texts and reading flows), and the secret that signs your events. You can't set those names yourself. The key shows on the API keys page, and is replaced on each deploy. - Up to 120 secrets per environment, of up to 5 KB each.
Limits
Each event, tool call or hook gets:
- Your flow's
timeout, as on your own server. The most is 5 s. - 10 fetches. The eleventh throws inside your code. You can catch it, and the event still finishes.
- A CPU limit of about 2 s, far above what a normal event uses, which is under 1 ms. Past it, the run stops, and the call takes its fallback with the reason
cpu_limit. It's a guard against runaway code, not a budget: see Pause for the average we hold you to.
Each fetch's host and status shows on the call's timeline as hcc:fetch <host> <status>. Request and response bodies are never logged.
When it fails
A hosted event that fails takes the same path as a self-hosted one: the step's fallback, then onError, then the number's Default flow. Each fallback is a call.flow.fallback Event, and two reasons are only for hosted code:
| Reason | What happened |
|---|---|
cpu_limit | Your code went over its CPU limit |
hosting_paused | Hosted code is paused, or turned off, or none is deployed in that environment yet |
Pause
While hosted code is paused, its events take the fallback path with hosting_paused, and calls end up on the Default flow. Self-hosted definitions aren't affected.
- An owner can pause it, and resume it, with the switch on the dashboard's Flows page.
- We pause it when it uses too much CPU: more than 50 ms per event on average over the last hour, once there have been at least 20 events. The Flows page shows why, and each owner gets an email. Fix the code, deploy, and an owner resumes it.
- Billing pauses live hosted code when it would stop new calls: no live plan, or a payment past its grace period. It runs again as soon as billing is in good standing, with nothing to resume. Test is never paused for billing.
- We can turn it off for a workspace that abuses it. Its hosted events then take the fallback path with
hosting_pauseduntil we turn it back on.
Logs
Each hosted run is on the Logs page, under Hosted code: its outcome, its CPU time, and what your code wrote with console, up to 50 lines. Runs are kept for 30 days. For live output while you work, use hcc dev.
Plans
Live hosted code is metered; test is free. An event is one flow event, one tool call, or one item in a hook batch.
| Plan | Included a month, per seat | Past that |
|---|---|---|
| Build | None | $5 per million events, $0.10 per million CPU ms |
| Team | None | $5 per million events, $0.10 per million CPU ms |
| Scale | 100,000 events and 1M ms of CPU | $5 per million events, $0.10 per million CPU ms |
A normal event uses under 1 ms of CPU, so a million events a month is about $5.10.
When to self-host
Keep a definition on your own server when it needs:
- A private system: a database or API behind your firewall, or one that only allows fixed IP addresses. Hosted code reaches the public internet only.
- Node-only packages, or anything that needs Node's built-in modules.
- Heavy CPU, such as parsing large files or running a model on each event.
You can host the rest, and keep only those on your server.