HCC Docs

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.ts still needs an endpoint for those. A project that's all hosted needs no endpoint and 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 dev runs 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 test

hcc 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 --check also compares the hosted code running with a fresh build.
  • A call in progress keeps its version: old versions are in the new bundle too.
  • --live uploads to both environments, each with its own secrets, and activates neither unless both loaded. --no-test uploads 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 key
  • set never takes the value as an argument, so it stays out of your shell history.
  • Live secrets take --live and a live key with secrets: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_KEY in a flow, or ctx.env.STRIPE_KEY in a tool.
  • Values you name with env('NAME'), such as an agent id, come from secrets too, so set one for each. hcc deploy warns about any env('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 secrets says it arrives with the next deploy.
  • We add our own: HCC_API_KEY in live and HCC_TEST_API_KEY in 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:

ReasonWhat happened
cpu_limitYour code went over its CPU limit
hosting_pausedHosted 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_paused until 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.

PlanIncluded a month, per seatPast that
BuildNone$5 per million events, $0.10 per million CPU ms
TeamNone$5 per million events, $0.10 per million CPU ms
Scale100,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.