Commands
Complete reference for TrustPin CLI commands.
Global Flags
Available on every command:
| Flag | Description |
|---|---|
--verbose | Verbose output: config file location, API URLs, HTTP status codes |
--debug | Debug output |
--log-http | Log HTTP requests and responses |
--version | Print the CLI version |
Most commands also accept --output json for machine-readable output.
Authentication
configure
Configure the CLI with your Personal Access Token.
trustpin-cli configure [--api-base-url <url>] [--api-token <token>]Interactive prompt:
$ trustpin-cli configure
API Base URL (https://api.trustpin.cloud): https://api.trustpin.cloud
API Token: tp_your_personal_access_token_here
Configuration saved successfully!Non-interactive (CI/CD):
Pass --api-base-url and --api-token to skip the prompts — useful in pipelines where you inject the token from a secret:
trustpin-cli configure \
--api-base-url https://api.trustpin.cloud \
--api-token "$TRUSTPIN_API_TOKEN"Get your Personal Access Token:
- Visit https://app.trustpin.cloud/account/access-tokens
- Click Create Token
- Copy the token (it starts with
tp_) - Use it with
trustpin-cli configure
Token permissions:
- User-scoped: Access all projects you have permission to view
- Can expire: Create a new token if yours expires
Environment variables (CI/CD):
You can skip configure entirely by exporting credentials — ideal for CI runners and containers:
export TRUSTPIN_API_BASE_URL=https://api.trustpin.cloud
export TRUSTPIN_API_TOKEN=tp_your_token_hereOtherwise, credentials are stored in ~/.trustpin/cli/config.properties.
Reset configuration:
If you need to reconfigure or clear your credentials:
# Remove configuration
rm -rf ~/.trustpin/
# Configure again
trustpin-cli configureUser
user info
Show the authenticated user and the organizations you belong to. Useful as a first call after configure to verify your token and to discover the organization IDs needed by the projects commands.
trustpin-cli user info [--output json]Examples:
# Human-readable format (default)
$ trustpin-cli user info
═══ User Information ═══
ID: 7bb1bbbd-b7fc-4e1a-893a-026d92c6356f
Name: TrustPin
Email: info@trustpin.cloud
── Organizations ──
• Personal Organization (fba3418e-b5ae-b273-4bab-6da6ae07ba99)# JSON format for automation
$ trustpin-cli user info --output json
{
"status": "success",
"operation": "user-info",
"data": {
"user": {
"id": "7bb1bbbd-b7fc-4e1a-893a-026d92c6356f",
"name": "TrustPin",
"email": "info@trustpin.cloud"
},
"organizations": [
{
"id": "fba3418e-b5ae-b273-4bab-6da6ae07ba99",
"name": "Personal Organization"
}
]
}
}Get your organization ID with jq:
trustpin-cli user info --output json | jq -r '.data.organizations[].id'Project Management
projects list
List all projects you have access to.
trustpin-cli projects list [--output json]Examples:
# Human-readable format (default)
$ trustpin-cli projects list
═══ Projects (2) ═══
── TrustPin Mobile App ──
ID: df9964a9-66bf-4673-9743-adee9ce6213e
Type: Managed CDN with Cloud Keys
Organization: Personal Organization
Domains: 4
── API Gateway ──
ID: 99acf096-79b9-4fa6-a115-14b35b224839
Type: Managed CDN with Bring Your Own Keys
Organization: Personal Organization
Domains: 2# JSON format for automation
$ trustpin-cli projects list --output json
{
"status": "success",
"operation": "projects-list",
"data": {
"projects": [
{
"id": "df9964a9-66bf-4673-9743-adee9ce6213e",
"name": "TrustPin Mobile App",
"organization_id": "fba3418e-b5ae-b273-4bab-6da6ae07ba99",
"organization_name": "Personal Organization",
"type": "Managed CDN with Cloud Keys",
"domains_count": 4
}
]
}
}Use with jq:
# Get all project IDs
trustpin-cli projects list --output json | jq -r '.data.projects[].id'
# Get project names
trustpin-cli projects list --output json | jq -r '.data.projects[].name'projects get
Show detailed information about a single project, including its type, public key, configuration version vs. published version, and per-domain pin counts.
trustpin-cli projects get <organization-id> <project-id> [--output json]Example:
$ trustpin-cli projects get fba3418e-b5ae-b273-4bab-6da6ae07ba99 df9964a9-66bf-4673-9743-adee9ce6213e
═══ Project Details ═══
Name: TrustPin Mobile App
ID: df9964a9-66bf-4673-9743-adee9ce6213e
Type: Managed CDN with Cloud Keys
Organization: Personal Organization (fba3418e-b5ae-b273-4bab-6da6ae07ba99)
Created: 2025-07-10T16:58:11.093900Z
Updated: 2025-07-18T08:43:11.140066Z
Configuration Version: 3
Published Version: 2
Warning: Latest configuration (v3) is not yet published (v2)
Public Key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyQ04pTptzBAqo8q6mhwvvwdJSnoxDpvhwir9SVNAscNTNAApbuaKaEA6Ua5zTfknWPjMONc9XJeDOb4ExUj8dQ==
Domains: 4
• Domain: trustpin.cloud
Updated: 2025-07-18T08:43:11.140066Z
Certificate Pins: 1
• Domain: api.trustpin.cloud
Updated: 2025-07-18T08:43:11.140066Z
Certificate Pins: 1The Configuration Version / Published Version lines tell you whether you have unpublished changes — run projects sign to publish them.
projects config
Fetch the current project configuration as the JWS payload (always JSON). This is the unsigned configuration that projects sign turns into a published JWS — handy for inspecting exactly which pins and expiry dates are stored before signing.
trustpin-cli projects config <organization-id> <project-id>Example:
$ trustpin-cli projects config fba3418e-b5ae-b273-4bab-6da6ae07ba99 df9964a9-66bf-4673-9743-adee9ce6213e
{
"status": "success",
"operation": "projects-config",
"data": {
"project": {
"id": "df9964a9-66bf-4673-9743-adee9ce6213e",
"organization_id": "fba3418e-b5ae-b273-4bab-6da6ae07ba99"
},
"config": {
"version": 3,
"domains": [
{
"domain": "trustpin.cloud",
"last_updated": "2025-07-18T08:43:11Z",
"pins": [
{
"algorithm": "sha256",
"pin": "heXXXV6YUWtMPE/dUyZ6ESBpkOibPSeHseRAnp4dQJg=",
"expires_at": "2025-09-02T05:43:19Z"
}
]
}
]
}
}
}projects upsert
Add or update a certificate pin for a domain in your project configuration.
trustpin-cli projects upsert <organization-id> <project-id> \
--domain <domain-name> \
--pin <type>:<value> \
[--expires <ISO8601-datetime>] \
[--dry-run] \
[--verbose] \
[--output json]Tip: Before adding fresh pins during a certificate rotation, run
projects cleanupto drop already-expired pins. This keeps the stored configuration tidy and avoids carrying dead pins into the next signed version.
Parameters:
| Parameter | Required | Description |
|---|---|---|
<organization-id> | Yes | Organization UUID |
<project-id> | Yes | Project UUID |
--domain | Yes | Domain name (e.g., api.example.com) |
--pin | Yes | Pin in format <type>:<value> |
--expires | No | Expiration date in ISO 8601 format |
--dry-run | No | Preview changes without applying them |
--verbose | No | Print extra detail about the request and the resulting change |
--output | No | Output format: human (default) or json |
Pin Types:
| Type | Description | Use Case |
|---|---|---|
sha256 | Certificate SHA-256 fingerprint | Must update pin on every certificate renewal |
sha512 | Certificate SHA-512 fingerprint | Must update pin on every certificate renewal |
spki-sha256 | SPKI SHA-256 fingerprint | Recommended - OWASP best practice |
spki-sha512 | SPKI SHA-512 fingerprint | Maximum security + OWASP best practice |
Why SPKI is recommended: SPKI (Subject Public Key Info) pins the public key, not the certificate. This is the OWASP-recommended approach for certificate pinning. When combined with TrustPin’s dynamic pin updates, it enables zero-downtime certificate rotation regardless of whether keys change during renewal.
Key Reuse (Optional): If you reuse the same private key during certificate renewal (e.g., certbot renew --reuse-key), the SPKI pin remains unchanged. However, most managed certificate services (AWS ACM, Let’s Encrypt default, Cloudflare) generate new key pairs on renewal, which changes the SPKI pin—but TrustPin’s dynamic updates handle this seamlessly.
Upsert Behavior:
The command is idempotent and follows these rules:
| Scenario | Action | Response |
|---|---|---|
| Domain exists, pin exists, same expiration | No-op | "action": "no_change" |
| Domain exists, pin exists, different expiration | Update | "action": "updated" |
| Domain exists, pin doesn’t exist | Add | "action": "added" |
| Domain doesn’t exist | Create + Add | "action": "added" |
Pin matching: Pins are matched by type + value. Expiration is not part of the match key.
Examples:
Extract and add SPKI SHA-256 pin:
# Extract SPKI SHA-256 from certificate
SPKI_SHA256=$(openssl x509 -in cert.pem -pubkey -noout | \
openssl pkey -pubin -outform der | \
openssl dgst -sha256 -binary | \
base64)
# Extract expiration date
EXPIRES=$(openssl x509 -in cert.pem -noout -enddate | \
cut -d= -f2 | \
xargs -I{} date -d "{}" -u +%Y-%m-%dT%H:%M:%SZ)
# Add pin to project
trustpin-cli projects upsert \
fba3418e-b5ae-b273-4bab-6da6ae07ba99 \
9caaea0a-80ea-013e-4e7b-cee6bfb52b36 \
--domain api.example.com \
--pin spki-sha256:$SPKI_SHA256 \
--expires $EXPIRES \
--output jsonOutput:
{
"status": "success",
"operation": "upsert",
"domain": "api.example.com",
"action": "added",
"pin": {
"type": "spki-sha256",
"value": "oxVSdCLgthL3M5Vnnzepq8WWlkUfRPYkpjLpm+wn+1o=",
"expires_at": "2026-04-13T08:37:02Z"
},
"config_version": {
"before": 2,
"after": 3
}
}Dry run to preview changes:
trustpin-cli projects upsert \
fba3418e-b5ae-b273-4bab-6da6ae07ba99 \
9caaea0a-80ea-013e-4e7b-cee6bfb52b36 \
--domain api.example.com \
--pin spki-sha256:$SPKI_SHA256 \
--expires 2026-04-13T08:37:02Z \
--dry-runOutput (dry run):
Dry run mode enabled - no changes will be made
Would send PATCH request to:
/organizations/fba3418e-b5ae-b273-4bab-6da6ae07ba99/projects/9caaea0a-80ea-013e-4e7b-cee6bfb52b36/config
Request body:
{
"domain": "api.example.com",
"pin": {
"type": "spki-sha256",
"value": "oxVSdCLgthL3M5Vnnzepq8WWlkUfRPYkpjLpm+wn+1o=",
"expires_at": "2026-04-13T08:37:02Z"
}
}Update expiration date only:
# Pin already exists, just update the expiration
trustpin-cli projects upsert \
fba3418e-b5ae-b273-4bab-6da6ae07ba99 \
9caaea0a-80ea-013e-4e7b-cee6bfb52b36 \
--domain api.example.com \
--pin spki-sha256:oxVSdCLgthL3M5Vnnzepq8WWlkUfRPYkpjLpm+wn+1o= \
--expires 2027-06-01T00:00:00ZOutput:
{
"status": "success",
"operation": "upsert",
"domain": "api.example.com",
"action": "updated",
"pin": {
"type": "spki-sha256",
"value": "oxVSdCLgthL3M5Vnnzepq8WWlkUfRPYkpjLpm+wn+1o=",
"expires_at": "2027-06-01T00:00:00Z"
},
"config_version": {
"before": 3,
"after": 4
}
}Add certificate SHA-256 pin:
# Extract certificate SHA-256
CERT_SHA256=$(openssl x509 -in cert.pem -outform der | \
openssl dgst -sha256 -binary | \
base64)
trustpin-cli projects upsert \
fba3418e-b5ae-b273-4bab-6da6ae07ba99 \
9caaea0a-80ea-013e-4e7b-cee6bfb52b36 \
--domain cdn.example.com \
--pin sha256:$CERT_SHA256 \
--expires 2026-04-13T08:37:02ZImportant Notes:
- Configuration is not published yet - After upserting, you must run
projects signto publish changes to the CDN - Multiple upserts before signing - You can upsert multiple domains/pins before signing once
- Idempotent operation - Safe to run multiple times; won’t duplicate pins
- Version tracking - Each upsert increments the configuration version
- No waiting period - Upsert is instantaneous; only signing publishes to CDN
Common Use Cases:
1. Add backup pin before certificate rotation:
# Add new certificate's pin while old cert is still active
trustpin-cli projects upsert $ORG_ID $PROJECT_ID \
--domain api.example.com \
--pin spki-sha256:$NEW_SPKI \
--expires 2027-06-01T00:00:00Z
# Sign and publish
trustpin-cli projects sign $ORG_ID $PROJECT_ID --password $MASTER_PASSWORD
# Wait 24-48 hours for mobile apps to fetch new config
# Then deploy new certificate to servers2. Update multiple domains with wildcard certificate:
# Same pin for multiple domains
for DOMAIN in api.example.com cdn.example.com www.example.com; do
trustpin-cli projects upsert $ORG_ID $PROJECT_ID \
--domain $DOMAIN \
--pin spki-sha256:$SPKI \
--expires $EXPIRES
done
# Sign once after all updates
trustpin-cli projects sign $ORG_ID $PROJECT_ID --password $MASTER_PASSWORD3. Certificate renewal with same key (SPKI unchanged):
# Only expiration changes, SPKI remains the same
trustpin-cli projects upsert $ORG_ID $PROJECT_ID \
--domain api.example.com \
--pin spki-sha256:$EXISTING_SPKI \
--expires $NEW_EXPIRES
# Sign and deploy immediately (no waiting needed - pin unchanged)
trustpin-cli projects sign $ORG_ID $PROJECT_ID --password $MASTER_PASSWORDExit Codes:
| Code | Meaning | Example |
|---|---|---|
| 0 | Success or no-op | Pin added, updated, or unchanged |
| 2 | API error | HTTP 401, 404, 500 |
| 4 | Validation error | Invalid domain, pin format, or type |
| 99 | Unexpected error | Network timeout, file I/O error |
See Also:
- DevOps Guide - Complete workflow with examples
- Projects Cleanup - Removing expired pins before upserting
- Projects Sign - Publishing configurations
projects cleanup
Remove already-expired certificate pins from every domain in a project. This is the recommended first step of a certificate-rotation workflow — run it before projects upsert so you only ever sign a configuration that still contains live pins.
trustpin-cli projects cleanup <organization-id> <project-id> [--dry-run] [--verbose] [--output json|text]What it does:
- Removes only pins whose expiration is non-null and in the past.
- Pins without an expiry are always kept.
- Domains are never removed — a domain left with zero pins still exists.
- The configuration version is incremented only when at least one pin is removed, so the operation is idempotent.
- It updates the stored configuration only — it does not re-sign or publish. Run
projects signafterwards to publish the cleaned configuration.
Parameters:
| Parameter | Required | Description |
|---|---|---|
<organization-id> | Yes | Organization UUID |
<project-id> | Yes | Project UUID |
--dry-run | No | Ask the server how many pins would be removed without changing anything |
--verbose | No | Print the per-domain breakdown of removed and kept pins |
--output | No | Output format: text (default) or json |
Examples:
Preview what would be removed (safe):
$ trustpin-cli projects cleanup \
fba3418e-b5ae-b273-4bab-6da6ae07ba99 \
361049fd-418c-f5b8-ab11-ea4686c2cea3 \
--dry-run --output json
{
"status": "success",
"operation": "projects-cleanup",
"data": {
"dry_run": true,
"removed_pins": 2,
"resource_name": "tprn::project::fba3418e-b5ae-b273-4bab-6da6ae07ba99::361049fd-418c-f5b8-ab11-ea4686c2cea3"
},
"execution_time_ms": 41
}Remove expired pins, then sign:
# 1. Drop expired pins from the stored configuration
trustpin-cli projects cleanup $ORG_ID $PROJECT_ID
# 2. Publish the cleaned configuration
trustpin-cli projects sign $ORG_ID $PROJECT_IDJSON output for automation:
$ trustpin-cli projects cleanup \
fba3418e-b5ae-b273-4bab-6da6ae07ba99 \
361049fd-418c-f5b8-ab11-ea4686c2cea3 \
--output json
{
"status": "success",
"operation": "projects-cleanup",
"data": {
"dry_run": false,
"removed_pins": 0,
"resource_name": "tprn::project::fba3418e-b5ae-b273-4bab-6da6ae07ba99::361049fd-418c-f5b8-ab11-ea4686c2cea3"
},
"execution_time_ms": 664
}The data.removed_pins count is 0 when nothing was expired (a no-op), and data.resource_name is the project’s full TrustPin resource name (tprn::project::<org-id>::<project-id>).
Exit Codes:
| Code | Meaning | Example |
|---|---|---|
| 0 | Success | Expired pins removed, or none to remove (no-op) |
| 2 | API error | HTTP 401, 404, 500 |
| 99 | Unexpected error | Network timeout, file I/O error |
See Also:
- Projects Upsert - Adding/updating pins
- DevOps Guide - Certificate Rotation - End-to-end rotation workflow
Configuration Signing
projects sign (Cloud Keys)
Sign and publish project configuration using cloud-managed keys.
trustpin-cli projects sign <organization-id> <project-id> [--password <master-password>] [--output json|text]By default you’re prompted for the master password interactively. In CI/CD, pass it non-interactively with --password / -p (inject it from a secret, e.g. --password "$MASTER_PASSWORD").
Example:
$ trustpin-cli projects sign fba3418e-b5ae-b273-4bab-6da6ae07ba99 df9964a9-66bf-4673-9743-adee9ce6213e
Master password: ****
[1/5] Getting project information
Project: TrustPin Mobile App (Managed CDN with Cloud Keys)
[2/5] Loading project configuration
Configuration loaded with 4 domains
[3/5] Preparing private key
Using cloud-managed private key
[4/5] Creating and signing JWT
JWT signed successfully
[5/5] Uploading signed configuration
Configuration published successfully!The configuration is now live and SDKs will use it immediately.
projects sign (BYOK)
Sign and publish project configuration using your own private key (Bring Your Own Key).
trustpin-cli projects sign <organization-id> <project-id> --private-key <path-to-pem-file> [--output json|text]Requirements:
- Private key must be in PEM format (
--private-key/-k) - Private key can be password-protected (you’ll be prompted, or pass
--password/-p)
Example:
$ trustpin-cli projects sign fba3418e-b5ae-b273-4bab-6da6ae07ba99 99acf096-79b9-4fa6-a115-14b35b224839 --private-key ./my-private-key.pem
Private key password: ****
[1/5] Getting project information
Project: API Gateway (Managed CDN with Bring Your Own Keys)
[2/5] Loading project configuration
Configuration loaded with 2 domains
[3/5] Preparing private key
Reading private key from file: ./my-private-key.pem
[4/5] Creating and signing JWT
JWT signed successfully
[5/5] Uploading signed configuration
Configuration published successfully!What happens on failure:
If signing fails, the previous configuration remains active. Your users are not affected. You can retry signing at any time.
projects jws
Fetch the published JWS (JSON Web Signature) configuration from the CDN.
This command retrieves the currently published certificate pinning configuration that mobile applications are fetching. The JWS is the signed configuration that was published by the sign command.
trustpin-cli projects jws <organization-id> <project-id> [flags]Flags:
| Flag | Description |
|---|---|
--decode | Decode and display JWS header and payload |
--verify | Verify JWS signature using public key from CDN |
--output-file <path> | Save JWS to file |
Use cases:
- Verify what configuration is currently published
- Debug mobile app pinning issues
- Validate that
signsuccessfully published the configuration - Download the JWS for testing, archival, or self-hosted CDN deployment
Examples:
Fetch raw JWS (default):
$ trustpin-cli projects jws fba3418e-b5ae-b273-4bab-6da6ae07ba99 df9964a9-66bf-4673-9743-adee9ce6213e
eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJkb21haW5zIjp7ImFwaS5leGFtcGxlLmNvbSI6W3sidHlwZSI6InNwa2ktc2hhMjU2IiwidmFsdWUiOiJveFZTZENMZ3RoTDNNNVZubnplcHE4V1dsa1VmUlBZa3BqTHBtK3duKzFvPSIsImV4cGlyZXNfYXQiOiIyMDI2LTA0LTEzVDA4OjM3OjAyWiJ9XX0sImlhdCI6MTczODk4NzIwMH0.kG7z2x3nF4mB8qW9pL5jD3rC6vT8sY1eN4hK2mO9iU7lP4aQ6wX8bV9nE5cR3fJ2dT7gH1sM4kL6pO8jU9qW3eVerify JWS signature:
$ trustpin-cli projects jws fba3418e-b5ae-b273-4bab-6da6ae07ba99 df9964a9-66bf-4673-9743-adee9ce6213e --verify
JWS signature valid
Signed with algorithm: ES256 (ECDSA P-256)
Public key verified from CDNDecode and display payload:
$ trustpin-cli projects jws fba3418e-b5ae-b273-4bab-6da6ae07ba99 df9964a9-66bf-4673-9743-adee9ce6213e --decode
JWS Header:
Algorithm: ES256
Type: JWT
Payload:
Spec: v1.0.0
Version: 3
Issued At: 2026-06-11T13:24:44Z
Domains: 1
- api.example.com (2 pins)
Current DB Version: 3
Published Version: 3
Published version is up to dateSave JWS to file:
$ trustpin-cli projects jws fba3418e-b5ae-b273-4bab-6da6ae07ba99 df9964a9-66bf-4673-9743-adee9ce6213e --output-file config.jws
JWS saved to: config.jwsPipe to mobile app simulator:
$ trustpin-cli projects jws fba3418e-b5ae-b273-4bab-6da6ae07ba99 df9964a9-66bf-4673-9743-adee9ce6213e | ./test-mobile-app
Testing certificate pinning with config...
All domains validated successfullyCommon workflows:
1. Verify deployment after signing:
# Sign configuration
trustpin-cli projects sign $ORG_ID $PROJECT_ID --password $MASTER_PASSWORD
# Verify it's published and valid
trustpin-cli projects jws $ORG_ID $PROJECT_ID --verify2. Archive configurations for compliance:
# Save with timestamp
trustpin-cli projects jws $ORG_ID $PROJECT_ID \
--output-file "archive/config-$(date +%Y%m%d-%H%M%S).jws"3. Deploy to self-hosted CDN:
# Download signed JWS
trustpin-cli projects jws $ORG_ID $PROJECT_ID --output-file config.jws
# Verify integrity
trustpin-cli projects jws $ORG_ID $PROJECT_ID --verify
# Upload to your CDN
aws s3 cp config.jws s3://your-bucket/trustpin/config.jwsExit Codes:
| Code | Meaning |
|---|---|
| 0 | Success (empty output when no JWS is published yet) |
| 2 | API error |
| 7 | Failed to write the JWS to --output-file |
| 8 | JWS signature verification failed |
| 99 | Unexpected error |
See Also:
- DevOps Guide - Advanced Use Cases - Self-hosted CDN deployment
- Projects Sign - Publishing configurations
Domain Lookup
domains certificates
Look up all known SSL/TLS certificates for a domain — the live certificate plus any certificates discovered via Certificate Transparency logs — along with their SHA-256, SHA-512, SPKI SHA-256, and SPKI SHA-512 fingerprints. Use this to find pins before adding them with projects upsert, without having to fetch and hash certificates by hand.
trustpin-cli domains certificates <domain-name> [--output json]Example:
$ trustpin-cli domains certificates api.example.com
═══ Certificates for api.example.com ═══
Total certificates: 2
── Certificate 1 ──
Common Name: api.example.com
Issuer: Let's Encrypt Authority X3
SHA-256: heXXXV6YUWtMPE/dUyZ6ESBpkOibPSeHseRAnp4dQJg=
SHA-512: JruxdWe96b/Uuzusl3ZRTQf23b+vZWO8wKGa55dl1tXq...
SPKI SHA-256: oxVSdCLgthL3M5Vnnzepq8WWlkUfRPYkpjLpm+wn+1o=
SPKI SHA-512: abc123def456...
Expires At: 2026-04-13T08:37:02Z
CAA Issuer: letsencrypt.org
CT Issuer CN: Let's Encrypt Authority X3
CT SCT Logs: 2
── Certificate 2 ──
Common Name: *.example.com
Issuer: DigiCert SHA2 Extended Validation Server CA
...Pin a discovered certificate (no manual openssl):
# Pull the SPKI SHA-256 of the live certificate and upsert it
SPKI=$(trustpin-cli domains certificates api.example.com --output json | \
jq -r '.data.certificates[0].spkiSha256')
trustpin-cli projects upsert $ORG_ID $PROJECT_ID \
--domain api.example.com \
--pin spki-sha256:$SPKI \
--expires 2026-04-13T08:37:02ZThis is the easiest way to discover pins — it replaces the manual openssl x509 ... | openssl dgst pipelines shown under projects upsert.
Output Formats
All commands support two output formats:
Human-Readable (Default)
Formatted output with colors and progress indicators, perfect for interactive use.
trustpin-cli projects listJSON
Machine-readable output for automation and CI/CD pipelines.
trustpin-cli projects list --output jsonJSON response structure:
{
"status": "success",
"operation": "command-name",
"data": {
// Command-specific data
}
}Exit Codes
Exit codes are stable across commands and safe to script against:
| Code | Meaning |
|---|---|
0 | Success |
1 | Configuration error (CLI not configured) |
2 | API error |
3 | Authentication error |
4 | Validation error (bad arguments or input) |
5 | Resource not found |
6 | Key error |
7 | File error |
8 | Cryptography error |
9 | Cancelled by user |
10 | Permission error |
99 | Unexpected error |
Getting Help
View help for any command:
# General help
trustpin-cli --help
# Command-specific help
trustpin-cli projects --help
trustpin-cli projects sign --help