Save a card
Saves a card the vault form tokenized (see GET /payment-methods/vault), with one of the member’s saved addresses as its billing address. Returns 201 with the saved method, or 202 when the card issuer requires 3-D Secure first: the verification id in the 202 follows the challenge through the card verification routes, which save the card once approved. Responses carry Cache-Control: no-store. Requires a writable member credential.
curl --request POST \
--url https://api.fluid.app/api/member/v2026-10/payment-methods \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"token": "tok_sandbox_4hQ8pZ2mXv9sLw3eRk7Ybc",
"exp_month": "03",
"exp_year": "2031",
"billing_address_id": "0192f4f0-7a8b-7c9d-8e0f-1a2b3c4d5e6f",
"card_holder": "Casey Brooks",
"default": true
}
'import requests
url = "https://api.fluid.app/api/member/v2026-10/payment-methods"
payload = {
"token": "tok_sandbox_4hQ8pZ2mXv9sLw3eRk7Ybc",
"exp_month": "03",
"exp_year": "2031",
"billing_address_id": "0192f4f0-7a8b-7c9d-8e0f-1a2b3c4d5e6f",
"card_holder": "Casey Brooks",
"default": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
token: 'tok_sandbox_4hQ8pZ2mXv9sLw3eRk7Ybc',
exp_month: '03',
exp_year: '2031',
billing_address_id: '0192f4f0-7a8b-7c9d-8e0f-1a2b3c4d5e6f',
card_holder: 'Casey Brooks',
default: true
})
};
fetch('https://api.fluid.app/api/member/v2026-10/payment-methods', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.fluid.app/api/member/v2026-10/payment-methods",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'token' => 'tok_sandbox_4hQ8pZ2mXv9sLw3eRk7Ybc',
'exp_month' => '03',
'exp_year' => '2031',
'billing_address_id' => '0192f4f0-7a8b-7c9d-8e0f-1a2b3c4d5e6f',
'card_holder' => 'Casey Brooks',
'default' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.fluid.app/api/member/v2026-10/payment-methods"
payload := strings.NewReader("{\n \"token\": \"tok_sandbox_4hQ8pZ2mXv9sLw3eRk7Ybc\",\n \"exp_month\": \"03\",\n \"exp_year\": \"2031\",\n \"billing_address_id\": \"0192f4f0-7a8b-7c9d-8e0f-1a2b3c4d5e6f\",\n \"card_holder\": \"Casey Brooks\",\n \"default\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.fluid.app/api/member/v2026-10/payment-methods")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"token\": \"tok_sandbox_4hQ8pZ2mXv9sLw3eRk7Ybc\",\n \"exp_month\": \"03\",\n \"exp_year\": \"2031\",\n \"billing_address_id\": \"0192f4f0-7a8b-7c9d-8e0f-1a2b3c4d5e6f\",\n \"card_holder\": \"Casey Brooks\",\n \"default\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/member/v2026-10/payment-methods")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"token\": \"tok_sandbox_4hQ8pZ2mXv9sLw3eRk7Ybc\",\n \"exp_month\": \"03\",\n \"exp_year\": \"2031\",\n \"billing_address_id\": \"0192f4f0-7a8b-7c9d-8e0f-1a2b3c4d5e6f\",\n \"card_holder\": \"Casey Brooks\",\n \"default\": true\n}"
response = http.request(request)
puts response.read_body{
"status": 201,
"data": {
"id": "0192f501-2b3c-7d4e-8f5a-6b7c8d9e0f1a",
"kind": "card",
"brand": "visa",
"last4": "5555",
"expires": {
"month": 3,
"year": 2031
},
"card_holder": "Casey Brooks",
"default": true,
"billing_address": {
"name": "Casey Brooks",
"address1": "742 Evergreen Terrace",
"address2": null,
"city": "Springfield",
"state": "IL",
"postal_code": "62704",
"country_code": "US"
},
"created_at": "2026-07-02T19:44:10.000000Z"
},
"meta": {
"request_uuid": "0192f520-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"timestamp": "2026-09-30T15:20:00Z"
}
}{
"status": 202,
"data": {
"id": "6f1c2a9e-3b7d-4c58-9e21-0a4d8b7c5e13",
"status": "required",
"method_content": null,
"fingerprinting_required": false,
"merchant_tx_id": "6f1c2a9e-3b7d-4c58-9e21-0a4d8b7c5e13"
},
"meta": {
"request_uuid": "0192f520-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"timestamp": "2026-09-30T15:20:00Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}Authorizations
A member credential in the Authorization: Bearer header: a member
session JWT, a portal JWT whose login is linked to a membership in
that company, or an opaque member token. The credential alone
identifies the member and company.
Body
The card token passed to the existing payment service.
111One of the member's saved addresses (/addresses).
Make the card the member's default once saved.
1The CVC token passed to the existing payment service.
1The cardholder name passed to the existing payment service.
1Optional issuer prefix reported by the vault form.
Optional card-brand hint reported by the vault form.
Browser fingerprint fields forwarded unchanged to the existing 3-D Secure flow.
curl --request POST \
--url https://api.fluid.app/api/member/v2026-10/payment-methods \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"token": "tok_sandbox_4hQ8pZ2mXv9sLw3eRk7Ybc",
"exp_month": "03",
"exp_year": "2031",
"billing_address_id": "0192f4f0-7a8b-7c9d-8e0f-1a2b3c4d5e6f",
"card_holder": "Casey Brooks",
"default": true
}
'import requests
url = "https://api.fluid.app/api/member/v2026-10/payment-methods"
payload = {
"token": "tok_sandbox_4hQ8pZ2mXv9sLw3eRk7Ybc",
"exp_month": "03",
"exp_year": "2031",
"billing_address_id": "0192f4f0-7a8b-7c9d-8e0f-1a2b3c4d5e6f",
"card_holder": "Casey Brooks",
"default": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
token: 'tok_sandbox_4hQ8pZ2mXv9sLw3eRk7Ybc',
exp_month: '03',
exp_year: '2031',
billing_address_id: '0192f4f0-7a8b-7c9d-8e0f-1a2b3c4d5e6f',
card_holder: 'Casey Brooks',
default: true
})
};
fetch('https://api.fluid.app/api/member/v2026-10/payment-methods', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.fluid.app/api/member/v2026-10/payment-methods",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'token' => 'tok_sandbox_4hQ8pZ2mXv9sLw3eRk7Ybc',
'exp_month' => '03',
'exp_year' => '2031',
'billing_address_id' => '0192f4f0-7a8b-7c9d-8e0f-1a2b3c4d5e6f',
'card_holder' => 'Casey Brooks',
'default' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.fluid.app/api/member/v2026-10/payment-methods"
payload := strings.NewReader("{\n \"token\": \"tok_sandbox_4hQ8pZ2mXv9sLw3eRk7Ybc\",\n \"exp_month\": \"03\",\n \"exp_year\": \"2031\",\n \"billing_address_id\": \"0192f4f0-7a8b-7c9d-8e0f-1a2b3c4d5e6f\",\n \"card_holder\": \"Casey Brooks\",\n \"default\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.fluid.app/api/member/v2026-10/payment-methods")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"token\": \"tok_sandbox_4hQ8pZ2mXv9sLw3eRk7Ybc\",\n \"exp_month\": \"03\",\n \"exp_year\": \"2031\",\n \"billing_address_id\": \"0192f4f0-7a8b-7c9d-8e0f-1a2b3c4d5e6f\",\n \"card_holder\": \"Casey Brooks\",\n \"default\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/member/v2026-10/payment-methods")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"token\": \"tok_sandbox_4hQ8pZ2mXv9sLw3eRk7Ybc\",\n \"exp_month\": \"03\",\n \"exp_year\": \"2031\",\n \"billing_address_id\": \"0192f4f0-7a8b-7c9d-8e0f-1a2b3c4d5e6f\",\n \"card_holder\": \"Casey Brooks\",\n \"default\": true\n}"
response = http.request(request)
puts response.read_body{
"status": 201,
"data": {
"id": "0192f501-2b3c-7d4e-8f5a-6b7c8d9e0f1a",
"kind": "card",
"brand": "visa",
"last4": "5555",
"expires": {
"month": 3,
"year": 2031
},
"card_holder": "Casey Brooks",
"default": true,
"billing_address": {
"name": "Casey Brooks",
"address1": "742 Evergreen Terrace",
"address2": null,
"city": "Springfield",
"state": "IL",
"postal_code": "62704",
"country_code": "US"
},
"created_at": "2026-07-02T19:44:10.000000Z"
},
"meta": {
"request_uuid": "0192f520-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"timestamp": "2026-09-30T15:20:00Z"
}
}{
"status": 202,
"data": {
"id": "6f1c2a9e-3b7d-4c58-9e21-0a4d8b7c5e13",
"status": "required",
"method_content": null,
"fingerprinting_required": false,
"merchant_tx_id": "6f1c2a9e-3b7d-4c58-9e21-0a4d8b7c5e13"
},
"meta": {
"request_uuid": "0192f520-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"timestamp": "2026-09-30T15:20:00Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}