photon project platform manages the resources a project sends and receives on
— SMS numbers, iMessage lines, email domains, WhatsApp Business numbers, and
voice routing.
Browse the automatic command reference.
List inventory
Each list command asks for a currently enabled ability, so one resource can appear in more than one list — a line that does both iMessage and voice shows up in both.nextPageToken applies to resources only — provisioning operations are
paginated for you.
Buy a number
sms purchase provisions one US local SMS number. --country US is the default;
use --area-code 415 to request a particular area code. imessage purchase
provisions one dedicated iMessage line. Both confirm first unless you pass
--force:
photon operation replay <local-id> resumes polling without buying anything
else. See Recoverable operations.
Release an SMS number
sms delete checks that the resource still has SMS ability, then releases it:
Cancel provisioning in progress
platform operation cancel asks Photon to withdraw an in-progress remote
provision:
OPERATION_NOT_CANCELLABLE if the
operation is past the point of no return or finished first. Cancelling here
does not remove the local journal record.
Connect an email domain
email connect starts SES and DNS verification. The CLI normalizes case, a
trailing root dot, and internationalized names before sending, and rejects
schemes, paths, ports, wildcards, IP addresses, and malformed labels locally:
--no-browser to print it without opening. The manual records are always
printed as a fallback.
In human output the command then keeps waiting until Photon verifies the
records. Ctrl-C or --no-wait stops the local wait without
cancelling remote verification.
--json returns as soon as DNS is prepared, so automation gets exactly one
connection object to act on. It contains dnsRecords and the remote
operation, plus automaticSetup with applyUrl, dnsProviderId, and
providerDisplayName when Domain Connect is available. If verification already
finished, it also contains the resulting resource.
Re-read the published instructions at any time with the remote operation ID —
this hits Photon directly and needs neither the original idempotency key nor
the local journal:
iMessage shared-line assignments
A dedicated iMessage line can be shared. An assignment binds one of your users to the line so their messages are attributed to them:--phone-number is required and must be E.164. The name and email fields are
optional and only affect how the user is presented.
assignment list shows active assignments. Add --include-released to see
released ones too:
{"assignments": [...]} for lists and {"assignment": ...} for a
single record.
WhatsApp Business
Each project has one connected WhatsApp Business account. Theaccount list
command returns zero or one account and includes its capacity, review status,
restrictions, and alerts. Account pagination is no longer supported.
List the connected account and active senders:
Human onboarding wizard
Runnumber add without --source in an interactive terminal. The wizard
first asks for one simple choice: Bring Your Own Number or Use a Photon
SMS Number.
- Bring Your Own Number opens focused dashboard onboarding and stops. Finish Meta Embedded Signup and verification in the browser; the CLI does not wait or refresh inventory.
- Use a Photon SMS Number lets you select an eligible existing number or buy a new US local SMS number. Purchased numbers remain in the project if you stop onboarding later.
- The wizard always asks which connected WABA to use, even when there is only one. Selecting a connected WABA provisions directly. Selecting Connect another WABA with Meta opens Embedded Signup while the terminal retrieves and displays the SMS OTP.
Automation and agent flows
Automation must pass--source; --json without it fails instead of opening
the human wizard.
Bring-your-own-number onboarding is a browser handoff:
handoff object
with its URL and next steps. Embedded Signup requires human browser
interaction, and the dashboard owns verification and final connection. Use
--no-browser when an agent cannot launch a browser; the same guide and URL
are returned with browserAttempted: false.
photon operation replay <local-operation-id>.
To use that Photon number with a new or different WABA, hand it to the
dashboard instead:
--new-waba and --waba-id are mutually exclusive. Photon source always
requires --voip-resource-id. BYON rejects WABA, Photon-resource,
display-name, and idempotency flags. --no-browser applies only to browser
handoffs.
WhatsApp sender JSON
WhatsApp sender output uses Meta and Photon’s explicit field names. The oldphoneNumber and verifiedName aliases are not emitted:
number list displays phone number, display name, name status, quality,
Photon source, and resource ID. Deletion confirms against
displayPhoneNumber:
Voice routing profiles
Voice inventory and voice routing answer different questions.voice list
shows resources with an active pstn_voice ability. A profile describes
where Photon should send an inbound call once that check passes.
default with profile view, profile edit, or any inbound or
outbound command.
The CLI uses /profiles/default to read that profile, then sends directional
changes through /profiles/{profileId} with the stable ID returned by the
read. The default cannot be renamed, deleted, or reassigned, and it must exist
before you can create an additional profile.
A line with no override follows the project default. Assigning an additional
profile creates an override; clearing it returns the line to the current
default. profile edit can rename an additional profile and change media
encryption on either an additional or the default profile. Inbound and
outbound delivery have dedicated commands beneath the profile. Editing requires
at least one of --name or --media-encryption; the default cannot be renamed.
SIP routes
A profile can carry one inbound SIP destination. The scheme picks the transport: baresip: normalizes to UDP, ;transport=tcp selects TCP,
;transport=udp selects UDP, and sips: selects TLS. Photon owns the
authoritative SIP syntax and public-host validation, so there are no separate
transport options. Use --media-encryption auto or --media-encryption srtp
on profile creation or editing; srtp requires encrypted media.
Default creation needs only --default; Photon assigns the immutable name
Default Profile. Additional profile creation requires --name. Both create
direction-neutral profiles, so configure delivery afterward. Use
inbound set to create or fully replace the destination, inbound edit to
change selected fields, and inbound clear to disable inbound delivery:
Endpoint credentials
Credentials are replaced as an atomic username and password pair. Passwords are never accepted as command-line options. With--sip-username and no
--sip-password-file, an interactive terminal prompts with hidden input;
non-interactive use reads the exact password from stdin.
A password file is read exactly as written — spaces and trailing newlines are
significant — so create it deliberately:
--debug
output and never written to the local journal. Omitting credential flags
preserves the existing write-only secret, --clear-sip-credentials clears both
fields, and --sip-username replaces the username and password together. The
CLI never sends a masked password from a previous response back to Photon.
Outbound credentials
Outbound calling supports credential lifecycle commands and password-preserving authentication edits:outbound enable creates the first credential for a profile with no active
outbound credential. It defaults to SHA-256 and always sends that explicit
choice to Photon. Select --digest-algorithm md5 only for weaker legacy
compatibility. Photon supports MD5 over the UDP, TCP, and TLS transports
returned in the outbound endpoint list. Enable output reports the active
algorithm and each endpoint’s transport, host, and port so the SIP client can
use the connection guidance returned by Photon.
outbound edit changes the active Digest algorithm while preserving the
username and password, including existing validity and rotation grace metadata.
Use it to switch algorithms on an enabled profile. MD5 is the weaker legacy
option; select it only for compatibility. Selecting SHA-256 can stop a PBX that
does not support it from authenticating. The command asks for confirmation;
use --force to skip the prompt in automation.
The CLI resolves default to its stable profile ID and sends the current
profile’s top-level version as expectedVersion. Even a same-value edit goes
to Photon so the server can validate that version and return its authoritative
result. A stale version produces VOICE_PROFILE_VERSION_CONFLICT: read the
current profile and retry. VOICE_OUTBOUND_OPERATION_PENDING instead means
credential setup or rotation must finish first. Resume the original enable or
rotate request with its original idempotency key, or replay its recovery
record; after it completes, read the current profile and retry the edit.
Edit output contains the returned outbound connection and authentication
metadata and profileVersion, with no password or display-once secret warning.
Algorithm edits require no idempotency key, operation journal entry, or secret
acknowledgement.
outbound rotate replaces an existing credential while preserving the
active Digest algorithm, so rotation intentionally has no algorithm flag;
normal keeps the previous credential valid for one hour, while emergency
removes that grace period. outbound revoke disables outbound calling. It does
not delete the profile, inbound route, or line assignments.
Enable and rotation output password at most once. Save it from stdout
immediately: the CLI never persists it or writes it to debug output. Before the
request, the CLI privately journals the exact profile reference, selected
enablement digest algorithm, rotation mode, and expectedVersion. If the
result is unresolved, rerunning the command with the same supplied idempotency
key or using operation replay resends that exact body without rereading the
now-mutated profile. An idempotent replay returns
password: null; the mutation succeeded, but the display-once password cannot
be reproduced.
After successful output is flushed, the recovery record is removed. Do not
rerun an already-confirmed success with its old key; deliberately rotate with
the returned profileVersion and a new idempotency key to issue another
password. An omitted idempotency key is generated for the current invocation.
A supplied key must identify only that same unresolved enable or rotation
action. The CLI also retries one transport interruption within an invocation
with the same key and unchanged request body.
Assignments
default when there is no override.
Inbound changes on a profile with assigned lines, outbound algorithm edits,
rotation or revocation, assignment changes, and profile deletion all require
confirmation.
--force skips only that prompt. Deleting an assigned profile additionally
needs --unassign-lines, which asks Photon to atomically clear the overrides,
return those lines to the default, and delete the profile.
JSON envelopes
profile list accepts mutually exclusive --default and --additional
filters.
The active
pstn_voice ability remains the source of truth for admission.
Saving or assigning a profile does not by itself grant voice access.