Automate PostMyForm with the CLI
The PostMyForm CLI can manage forms from local scripts and CI jobs without using dashboard-specific automation.
Use the CLI when automation can run an approved executable and needs a small command-line interface to the public PostMyForm API.
Use PostMyForm MCP when an authorized AI agent already works through an MCP-compatible client.
Use the PostMyForm API reference and public OpenAPI contract when a custom integration needs direct control of HTTP requests and responses.
For installation and the complete released command reference, see the PostMyForm CLI documentation.
Verify the CLI before automation
The examples in this guide use the released PostMyForm CLI interface.
Check the installed version:
postmyform --version
Compare the result with the current PostMyForm CLI releases.
The CLI does not update itself automatically.
Pin or otherwise control the CLI version used by important automation so a release change does not enter a job unexpectedly.
Create a dedicated automation credential
Use a PostMyForm API credential created for the automation task.
Grant only the scopes that the job requires:
forms:readfor form, field, and generated-HTML read operations;forms:writefor form creation, form updates, and field replacement.
A read-only inspection job needs only forms:read.
A job that reads current state and then changes a form normally needs
both forms:read and forms:write.
Prefer a dedicated automation credential instead of reusing a personal credential.
Rotate or revoke the credential when the automation is retired or no longer needs access.
Credential setup is an account task. Automation should not depend on the current authenticated dashboard layout.
Inject the credential through the environment
The CLI reads the API credential from:
POSTMYFORM_API_TOKEN
Never put the token in:
- a command-line argument;
- a URL;
- workflow source;
- a repository file;
- generated artifacts;
- logs;
- screenshots;
- documentation.
For CI, store the token in the CI platform's protected secret or
protected-environment mechanism and expose it to the CLI process as
POSTMYFORM_API_TOKEN.
Do not print the variable.
Avoid shell tracing such as set -x when commands could expose
sensitive environment values.
Keep automation portable
The released CLI provides native binaries for supported Linux, macOS, and Windows environments.
The PostMyForm command names and API behavior stay the same across supported platforms. Environment-variable and secret-injection syntax depends on the shell and automation platform.
Use the platform's normal protected environment or secret mechanism to
provide POSTMYFORM_API_TOKEN.
Do not convert the token into a command-line argument to make an example portable.
See the PostMyForm CLI documentation for the current supported release artifacts and installation instructions.
Local shell automation
For a temporary local Bash session, read the credential without echoing it:
read -rsp "PostMyForm API token: " POSTMYFORM_API_TOKEN
echo
export POSTMYFORM_API_TOKEN
Verify the installed CLI:
postmyform --version
List forms as JSON:
postmyform forms list --json
Read one form as JSON:
postmyform forms get FORM_ID --json
Read its fields as JSON:
postmyform forms fields get FORM_ID --json
Update a selected property when required:
postmyform forms update FORM_ID \
--name "Website Contact"
Then request the generated form HTML:
postmyform forms snippet FORM_ID > form.html
A script must stop if a state-changing command fails or has an uncertain result. Do not continue as if the mutation succeeded.
When the automation session is complete, remove the credential from the shell environment:
unset POSTMYFORM_API_TOKEN
Create a form from automation
A form requires a name and destination email.
The released CLI supports JSON output for form creation:
postmyform forms create \
--name "Contact" \
--destination-email "contact@example.com" \
--allowed-origin "https://example.com" \
--json
Use the returned form ID for later commands.
Creating a form changes server state. Do not automatically retry the command when the result is uncertain.
Replace form fields
Read the current field collection first:
postmyform forms fields get FORM_ID --json
If a replacement is required, provide the complete ordered field collection:
postmyform forms fields replace FORM_ID \
--file fields.json
fields replace replaces the complete field collection. It does not
append fields.
The input file must contain form field configuration, not credentials.
Do not store POSTMYFORM_API_TOKEN in fields.json or any other
repository file.
Field replacement changes server state. Do not automatically retry it when the result is uncertain.
Use machine-readable output
Commands that support structured output use --json.
The released CLI supports JSON output for representative operations such as:
postmyform forms list --json
postmyform forms get FORM_ID --json
postmyform forms fields get FORM_ID --json
Form creation also supports --json.
JSON data is written to standard output.
Errors are written to standard error.
Automation should consume JSON when structured output is available and should test the process exit code instead of parsing human-readable error messages.
Exit codes
The released CLI uses these exit codes:
| Code | Meaning |
| ---: | --- |
| 0 | Success |
| 2 | Invalid command, option, input, or local configuration |
| 3 | Authentication or authorization failure |
| 4 | PostMyForm API or response failure |
| 5 | Network or transport failure |
A nonzero exit code should fail the current automation step unless the caller has an explicit, bounded policy for that specific failure.
Do not hide failures with a broad retry loop.
Rate limits and retries
Read operations may be retried under a bounded client policy when the failure is known to be safe to retry.
A PostMyForm API rate-limit response is reported by the CLI as an API
failure with exit code 4.
When a 429 response contains a supported positive integer
Retry-After value, the released CLI writes a line like this to
standard error:
Retry-After: 30
A caller that deliberately retries a read operation should respect that delay and keep the retry count bounded.
Do not treat a state-changing command as automatically retryable.
This applies to:
postmyform forms create;postmyform forms update;postmyform forms fields replace.
If one of these commands fails or its result is uncertain, fail the job unless the caller has independently established that repeating the specific operation is safe.
The CLI does not automatically retry mutations.
Bounded CI example
The same security model applies to any CI provider:
- create a dedicated PostMyForm automation credential;
- grant only the required scopes;
- save it in the provider's protected secret mechanism;
- inject it as
POSTMYFORM_API_TOKEN; - run bounded CLI commands;
- fail the job on unsuccessful mutations;
- do not upload the credential as an artifact.
The following GitHub Actions fragment is one example. PostMyForm does not require GitHub Actions.
Store the PostMyForm credential as a protected repository or
environment secret named POSTMYFORM_API_TOKEN.
Store the non-secret form ID as an appropriate workflow variable.
jobs:
verify-form:
runs-on: ubuntu-latest
env:
POSTMYFORM_API_TOKEN: ${{ secrets.POSTMYFORM_API_TOKEN }}
FORM_ID: ${{ vars.POSTMYFORM_FORM_ID }}
steps:
- name: Verify PostMyForm CLI
run: postmyform --version
- name: Read form configuration
run: postmyform forms get "$FORM_ID" --json > form.json
- name: Read form fields
run: postmyform forms fields get "$FORM_ID" --json > fields.json
- name: Get generated form HTML
run: postmyform forms snippet "$FORM_ID" > form.html
This example is read-only and needs only forms:read.
How the CLI executable is installed or restored in a CI image depends on the CI environment. Use the released artifacts and verification instructions in the CLI documentation.
Do not place a literal token in the workflow file.
Do not print the environment or upload files that could contain credentials.
CI mutation example
A CI job that intentionally changes form configuration needs
forms:write. If it also reads current state, it needs forms:read.
For example:
jobs:
update-form:
runs-on: ubuntu-latest
env:
POSTMYFORM_API_TOKEN: ${{ secrets.POSTMYFORM_API_TOKEN }}
FORM_ID: ${{ vars.POSTMYFORM_FORM_ID }}
steps:
- name: Verify PostMyForm CLI
run: postmyform --version
- name: Read current form
run: postmyform forms get "$FORM_ID" --json
- name: Update form name
run: postmyform forms update "$FORM_ID" --name "Website Contact"
The mutation step is intentionally a single command with no retry loop.
If it returns a nonzero exit code, the CI step should fail.
Do not add an automatic retry wrapper around the mutation merely to make the job pass.
Alternate API endpoint
The CLI uses the production API by default:
https://postmyform.com/api/v1
Most automation should leave the default unchanged.
For an approved alternate environment, the released CLI supports:
POSTMYFORM_API_BASE_URL
Remote endpoints must use HTTPS.
Plain HTTP is accepted only for loopback addresses during local testing.
Do not put a token in the API base URL.
Automation boundaries
The released CLI manages forms, form fields, and generated form HTML through the supported public API.
It does not provide CLI commands for:
- reading form submissions;
- exporting submission data;
- billing administration;
- Slack or Discord destination management;
- operator functions;
- repository commits;
- website deployment;
- private backend routes.
If automation must edit or deploy a website, use a separate tool with separate authorization for that task.
Keep automation deterministic
Prefer small jobs that:
- verify the expected CLI version;
- use a dedicated least-privilege credential;
- read current state before changing existing configuration;
- consume
--jsonwhere structured output is supported; - perform only the required mutation;
- fail clearly on a nonzero exit code;
- avoid broad retry loops;
- obtain generated HTML from PostMyForm;
- clean up temporary credentials in local environments.
For complete CLI command details, see the PostMyForm CLI documentation.
For direct HTTP schemas and public API behavior, see the PostMyForm API reference and PostMyForm OpenAPI contract.