Get Card Art
GET https://api.firmly.work/api/v1/wallets/agentic-pay/card-art/{token}
Overview
Returns the card art image (the visual card image from the issuing bank) for a card enrolled via Agentic Pay. The URL is returned in the card_art.url field of the enroll response and in the Wallet Complete Order response (where it appears under payment_summary.card_art). No authentication header is needed — the HMAC-signed token in the URL path serves as authorization.
Authentication
This endpoint requires no authentication. The token path parameter contains an HMAC-signed payload that serves as authorization.
Path Parameters
token(string, required) — HMAC-signed compact token in the format<base64url-payload>.<signature>. Contains the network, image locator, and expiry. Generated by Firmly during enrollment.
Response
The response is binary image data with the following headers:
-
content-type(string) —image/pngorimage/jpegdepending on the card art source -
cache-control(string) —public, max-age=86400, immutable -
x-firmly-card-art-source(string) — Source identifier for the card art image
Card Art Object Shape
The card_art object returned by /enroll has this shape. Destinations should persist it from the initial enrollment for use in the saved-card UI:
-
card_art.network(string) — Card network (visa,mastercard, ordiscover) -
card_art.url(string) — Full URL to this card-art endpoint with the signed token -
card_art.background_color(string) — Hex color code for the card background (e.g.,#1A1F71) -
card_art.foreground_color(string) — Hex color code for the card foreground text (e.g.,#FFFFFF) -
card_art.descriptor(string) — Issuing bank descriptor (e.g.,"Test Bank 2")
Code Examples
# Use the URL directly from the enroll or complete responsecurl -o card-art.png \"https://api.firmly.work/api/v1/wallets/agentic-pay/card-art/eyJuIjoiVklTQSIsImx..."
// The card_art.url from the enroll/complete response can be used directlyconst enrollResponse = await enroll(cardDetails);const { card_art } = enrollResponse;// Drop directly into an img tagconst img = document.createElement('img');img.src = card_art.url;// Or fetch the image programmaticallyconst response = await fetch(card_art.url);const contentType = response.headers.get('content-type');const blob = await response.blob();const imageUrl = URL.createObjectURL(blob);
import requests# Use the URL from the enroll/complete responsecard_art_url = enroll_response["card_art"]["url"]response = requests.get(card_art_url)content_type = response.headers["content-type"]# Save to fileextension = "png" if "png" in content_type else "jpeg"with open(f"card-art.{extension}", "wb") as f:f.write(response.content)
Response Example
{"card_art": {"network": "visa","url": "https://api.firmly.work/api/v1/wallets/agentic-pay/card-art/<signed-token>","background_color": "#1A1A2E","foreground_color": "#FFFFFF","descriptor": "Test Bank 2"}}
How the Proxy Works
The card-art endpoint acts as a secure proxy between the destination and the card network’s asset service. Firmly fetches the image using its own network credentials, so destinations never need direct access to network asset APIs. The token has a default TTL of 1 hour.
Error Responses
Errors are returned as JSON, not as image data.
| Error Code | Status | Description |
|---|---|---|
BadRequest |
400 | Malformed token or locator host not allowed |
Unauthorized |
401 | Signature invalid or token expired |
PaymentMethodNotAvailable |
409 | Card art not found at the network (e.g., nonexistent Visa GUID) |
400 - Bad Request
{"code": 400,"error": "BadRequest","description": "Malformed token or locator host not allowed"}
401 - Unauthorized
{"code": 401,"error": "Unauthorized","description": "Signature invalid or token expired"}
409 - Card Art Not Found
{"code": 409,"error": "PaymentMethodNotAvailable","description": "Card art not found at the network"}
Related Endpoints
- Enroll Card — Enroll a card and receive the
card_artobject in the response - Intent Challenge — Complete a payment-level challenge for the intent