card_ingest url, and the card is posted to that url.
the card_ingest url is served by KERNEL’s PCI-compliant card vault, not by KERNEL’s API. the card vault replaces the card number and CVC with aliases before the request reaches KERNEL, so KERNEL never handles raw card data. the agent’s browser only ever sees aliases, which are swapped for the real values on the way to the merchant.
the request carries the raw card number and CVC, so it must come from an environment that’s allowed to handle them. there are two common ways to send it:
- from a card issuer. a bank, card program, or payment provider creates a single-use card for one checkout and posts it from its own PCI-compliant backend. use this for virtual cards issued per purchase.
- from your own card vault. your cards already live in a third-party vault, such as VGS, Basis Theory, Skyflow, or Evervault. your backend sends the request with your vault’s aliases through the vault’s outbound proxy, which swaps in the real values on the way out. the raw card only exists between the two vaults, so your servers never handle it. see push from your own card vault.
server enrollment is enabled per organization.
add_payment_method with enrollment: "server" returns 409 until it’s configured for your organization. contact support to enable it.How it works
Start a server enrollment
invokeadd_payment_method on a connected KERNEL wallet with enrollment: "server". the result is a payment method in pending_enrollment whose action is a card_ingest url that expires 5 minutes later. each call creates a separate url for one card.
Push the card
post the card as JSON to the exactcard_ingest url, with a KERNEL API key in the Authorization header. the key must belong to the wallet’s organization and have vaults:use and vaults:write on the vault. if the wallet isn’t in your organization’s default project, send the same X-Kernel-Project header you used to start the enrollment.
send every card value as a string, and send no other fields. the body must be
application/json and under 8 KB.
From a card issuer
the issuer posts the card directly from its PCI-compliant backend:Push from your own card vault
if your cards are in a third-party vault, send the same request from your backend with your vault’s aliases incard.number and card.cvc, routed through your vault’s outbound proxy. configure the proxy to reveal those two fields on requests to the card_ingest url’s host, so the real values only exist between your vault and KERNEL’s card vault. the exact setup depends on your vault; see its outbound proxy or reveal documentation.
your vault needs a CVC for the card. most vaults don’t keep a CVC for stored cards, so collect it again, or keep it only for the short time your vault allows, before each push.
422, or stores an unusable card that fails at checkout, so test the setup with a test card first.
Response
a successful push returns200 with the payment method, now active:
Errors
errors return JSON with acode and a message. KERNEL never logs the request body or card values.
Retries
if you lose the response, retry the same request to the same url. a retry with the same card,network, last4, issuer_reference, and valid_until returns 200 with the same payment method, so you can tell the card was stored. a different card on a used url returns 409.
once the card’s CVC has been used by a purchase or has expired, a retry returns 409 enrollment_used. to push the card again, start a new server enrollment.
Pay with the pushed card
create a purchase with the pushed card’sid as spec.payment_method_id, as in choose a card for a purchase. because the CVC came with the card, authorize makes the purchase ready right away, with no cardholder approval page. the agent then fills the checkout as usual.
- one purchase per push. the first purchase to authorize takes the CVC. other purchases on the same card show
funding_status: "unavailable"and noauthorizeoperation, and authorizing them returns409. if the first purchase fails before it’s issued, the CVC goes back to the card for another purchase. - the CVC window starts at the push. the CVC stays usable for 5 minutes by default, or up to an hour depending on your organization’s card vault, and never past
valid_until. the push,authorize, and fill must all happen inside that window, so push the card when the checkout is ready to run. the purchase expires when the CVC does. - after the purchase. the card stays in the wallet as
activebut lists as ineligible with the reasoncvc_unavailable, orvalid_until_passedaftervalid_until. remove it withremove_payment_method, and push the card again for the next checkout.
Limit what a pushed card can pay for
KERNEL doesn’t bind a pushed card to a merchant or an amount, and there’s no cardholder approval step. any API key withvaults:use on the vault can spend the card while its CVC is valid.
- issuer cards: issue single-use cards that only work at the intended merchant, for the intended amount, and only until
valid_until. - cards from your own vault: these are usually regular cards with no such limits, so push a card only when its checkout is about to run, set a short
valid_until, and restrict which API keys havevaults:useon the vault.