Skip to main content

extendvcc

CI PyPI License: MIT Python 3.11+

Unofficial CLI and Python client for the Extend virtual card API.

Disclaimer

This is an unofficial, independent client for Extend's private browser API (api.paywithextend.com). It is not affiliated with, endorsed by, or supported by Extend, Inc. Use at your own risk. Your Extend account may be suspended for running automation against their private API.

Install

pip install extendvcc-cli
# or
pipx install extendvcc-cli

Standalone binary (no Python required): download from GitHub Releases.

Quick Start

# Log in: prompts for email, password, and the emailed OTP. Device is remembered,
# so you won't be asked again on this machine for a while. No setup required.
extendvcc login

# List parent cards
extendvcc accounts

# List virtual cards
extendvcc cards

Enroll a Parent Card

Enrolling a parent card is a three-step lifecycle:

# 1. Register the card (prompts for card number + CVC; triggers an issuer
#    verification email). Card details are typed at a prompt, never passed as flags.
extendvcc enroll \
  --display-name "My Amex" \
  --cardholder-name "Jane Doe" \
  --issuer-id iss_xxx \
  --expires 2028-12-31 \
  --address1 "123 Main St" \
  --city "Springfield" \
  --province "IL" \
  --postal "62701"

# 2. Your card issuer (e.g. Amex) emails you a verification request. Open it and
#    approve manually before activation will succeed.

# 3. Pull the card from PENDING to ACTIVE. Re-run if it still reports PENDING.
extendvcc activate <card-id>

Run extendvcc issuers to find the --issuer-id for your card.

Update a Parent Card's Billing Address

Change the stored billing address on a parent (SOURCE) credit card:

extendvcc update-account cc_2vtDvRzWDB19myGfM9naDD \
  --address1 "357 Dawson Drive" \
  --city "Santa Clara" \
  --province CA \
  --postal 95051

--address2 and --country are optional; an omitted --country keeps the card's current value. Preview the exact request body without mutating (does a read-only GET):

extendvcc update-account cc_... --address1 "..." --city "..." --province CA --postal 95051 --dry-run

Note: this changes the stored billing address on the parent card. Whether it affects address verification (AVS) at checkout is issuer-dependent and unverified — confirm against a live transaction before relying on it.

Create a One-Time Card

extendvcc create \
  --credit-card-id cc_xxx \
  --name "My Card" \
  --balance-cents 5000 \
  --valid-to 2026-12-31

Create a Recurring Card

extendvcc create \
  --credit-card-id cc_xxx \
  --name "Monthly" \
  --balance-cents 10000 \
  --period MONTHLY \
  --by-month-day 1 \
  --terminator NONE

Reveal Credentials

# Show masked card number and CVC on stdout
extendvcc reveal <card-id>

# Write full credentials to a file with 0600 permissions (owner-only)
extendvcc reveal <card-id> --json-path creds.json

--json-path writes the full PAN, CVC, and expiry to a file. Without it, the card number is masked on stdout. --json is a separate global flag that controls JSON output format; it does not write a file.

Credential Storage

After you log in once, the CLI keeps you signed in so you don't retype your password every time. Here is exactly what lands on your machine and why it's safe.

The tool stores a session file at ~/.config/extendvcc/paywithextend_session.json (or wherever EXTENDVCC_STATE_DIR points). It holds the access and refresh tokens Extend hands back after login, plus a remembered-device key. It does not contain your Extend password. Your password is sent to Extend's login endpoint and never written to disk.

The file is created with 0600 permissions, so only your user account can read it. Tokens expire and are refreshed automatically. Still, treat the file as sensitive: a current access token lets someone act on your Extend account until it expires or you delete the session. Don't copy it to shared machines or commit it anywhere.

There is no logout command. To sign out on a device, delete the session file:

rm ~/.config/extendvcc/paywithextend_session.json

The next command will prompt for a fresh login. If you set EXTENDVCC_EMAIL, EXTENDVCC_PASSWORD, or the IMAP variables for automation (see below), those live in your shell environment or secrets manager, not in this file, and the tool never persists them.

Dry Run

Destructive commands accept --dry-run to preview the exact operation without touching the network or mutating anything:

extendvcc create --credit-card-id cc_x --name "Test" --balance-cents 5000 --valid-to 2026-12-31 --dry-run
extendvcc bulk cards.csv --credit-card-id cc_x --dry-run
extendvcc cancel <card-id> --dry-run
extendvcc close <card-id> --dry-run
extendvcc update <card-id> --balance-cents 9000 --dry-run
extendvcc update-account <cc-id> --address1 "1 New Rd" --city "Newtown" --province CA --postal 95051 --dry-run

The would-be request body (or operation descriptor) is printed as JSON to stdout; the human-readable plan goes to stderr. So extendvcc create ... --dry-run > body.json captures just the JSON. create/bulk resolve the recipient locally (from --recipient, else the saved session) and never call the API; the preview is labelled approximate when the recipient falls back to a placeholder. update --dry-run performs only the read-only GET needed to show the accurate merged PUT body, with no mutation.

Exit Codes

The CLI uses stable exit codes so scripts and CI can branch on the outcome:

Code Name Meaning
0 OK Success.
1 ERROR Generic failure (library error, or an aborted confirmation).
2 USAGE Bad flags or CLI input validation (e.g. missing --valid-to).
3 AUTH_REQUIRED Login, OTP, or a saved session is required or failed.
4 DISABLED Kill switch tripped (account-risk); run clear-disabled --manual.
5 API_ERROR Extend returned an error response.

Unattended / Automation Use

You can skip this entire section for normal use. extendvcc login prompts for everything it needs. The variables below only matter when you want to run the CLI with no human present (a cron job, CI pipeline, or script), where there's nothing to type into a prompt.

To log in non-interactively, supply the credentials as environment variables. Extend still requires a one-time code (OTP) emailed on login; set the IMAP variables so the CLI can read that code from your inbox automatically. If IMAP retrieval times out, it falls back to a manual prompt.

Variable Purpose
EXTENDVCC_EMAIL Extend account email (replaces the email prompt)
EXTENDVCC_PASSWORD Extend account password (replaces the password prompt)
EXTENDVCC_IMAP_USER Inbox address to read the login OTP from
EXTENDVCC_IMAP_PASSWORD IMAP app password for that inbox
EXTENDVCC_IMAP_HOST IMAP server (default: imap.gmail.com)

Inject these from your secrets manager or CI vault at runtime. Don't commit them to a file.

Advanced overrides

Rarely needed. Change only if the defaults don't fit your setup.

Variable Purpose
EXTENDVCC_STATE_DIR Override session/state directory
EXTENDVCC_LEDGER_PATH Override ledger file path
EXTENDVCC_BRAND_ID Override Extend brand ID

Python API

from extendvcc import list_cards, get_card, create_card, reveal_card

# List all virtual cards
cards = list_cards()

# Get a single card by ID
card = get_card("card_id_here")

# Reveal card credentials (PAN, CVC, expiry)
creds = reveal_card("card_id_here")

# Update a parent card's billing address
from extendvcc import update_credit_card_address

update_credit_card_address(
    "cc_id_here",
    {"address1": "357 Dawson Drive", "city": "Santa Clara", "province": "CA", "postal": "95051"},
)

See extendvcc.__init__ for the full list of exported functions and models.

Testing

The pytest suite runs entirely offline against fakes. It never touches the network.

Security Notes

  • The ledger never stores PAN or CVC data.
  • reveal saves credentials with 0600 file permissions.
  • Session tokens are stored locally with restricted permissions.
  • All HTTP uses Chrome TLS fingerprinting via impit.

License

MIT

Metadata

Release files for extendvcc-cli 0.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for extendvcc-cli 0.2.2
File Size Uploaded Provenance Actions
extendvcc_cli-0.2.2.tar.gz 117.2 kB With provenance Details for extendvcc_cli-0.2.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for extendvcc-cli 0.2.2
File Interpreter ABI Platform Actions
extendvcc_cli-0.2.2-py3-none-any.whl Python 3 none any Details for extendvcc_cli-0.2.2-py3-none-any.whl

Total release size: 169.1 kB

Release files / extendvcc_cli-0.2.2.tar.gz

Download URL extendvcc_cli-0.2.2.tar.gz
Size 117.2 kB
Tags Source
SHA-256 checksum
How to use checksums
2b8bdd81fe0253b12bc27dcd029ba61ceb3413ee00b58ec0d3e02e8c518743b3
BLAKE2b-256 checksum
How to use checksums
0c67590e0c3081b8941a293a8c46f63c81ab8cc258a0bf041fbe9320a81bc70e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 9, 2026.

Transparency log

Release files / extendvcc_cli-0.2.2-py3-none-any.whl

Download URL extendvcc_cli-0.2.2-py3-none-any.whl
Size 51.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
18eb9f414e3f53a199a3685803583ef00c9a866668e0cb15cb869c17cccabc68
BLAKE2b-256 checksum
How to use checksums
f189a68b6df64caeabc294df796e3c3391e92088acdbbd744ff3836a7e2de91c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 9, 2026.

Transparency log

Security for extendvcc-cli 0.2.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for extendvcc_cli-0.2.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 9, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page