Change a subscription's texts choice
Opts a phone in or out of the company’s recurring subscription texts from the manage page. An opt-in records the disclosure text the customer saw, the request’s IP address and user agent, and the customer as the actor. The first opt-in for a phone also queues one confirmation text. An opt-out needs no current disclosure, and it also opts out the phone that the subscription’s renewal reminders go to when that is another phone. Only US and Canadian phone numbers are accepted, and the response gives the phone in E.164 form.
Requires the bearer token of the customer who owns the subscription. A
manage link token (sml_...) is not accepted, because that link travels
to merchant systems and must never write opt-in evidence. Returns 404
for a subscription that is not the customer’s and when subscription texts
are not available to the company, and 401 when unauthenticated. Returns
422 with an error_code of invalid_params, stale_disclosure for
an opt-in that names an old version (the response names the current
version in current_version),
unsupported_phone_country or invalid.
curl --request PUT \
--url https://api.fluid.app/api/checkout/v2026-04/subscriptions/{token}/sms-consent \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"opted_in": true,
"phone": "(415) 555-2671",
"disclosure_version": "2026-10-draft-1"
}
'import requests
url = "https://api.fluid.app/api/checkout/v2026-04/subscriptions/{token}/sms-consent"
payload = {
"opted_in": True,
"phone": "(415) 555-2671",
"disclosure_version": "2026-10-draft-1"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({opted_in: true, phone: '(415) 555-2671', disclosure_version: '2026-10-draft-1'})
};
fetch('https://api.fluid.app/api/checkout/v2026-04/subscriptions/{token}/sms-consent', 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/checkout/v2026-04/subscriptions/{token}/sms-consent",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'opted_in' => true,
'phone' => '(415) 555-2671',
'disclosure_version' => '2026-10-draft-1'
]),
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/checkout/v2026-04/subscriptions/{token}/sms-consent"
payload := strings.NewReader("{\n \"opted_in\": true,\n \"phone\": \"(415) 555-2671\",\n \"disclosure_version\": \"2026-10-draft-1\"\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.fluid.app/api/checkout/v2026-04/subscriptions/{token}/sms-consent")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"opted_in\": true,\n \"phone\": \"(415) 555-2671\",\n \"disclosure_version\": \"2026-10-draft-1\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/checkout/v2026-04/subscriptions/{token}/sms-consent")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"opted_in\": true,\n \"phone\": \"(415) 555-2671\",\n \"disclosure_version\": \"2026-10-draft-1\"\n}"
response = http.request(request)
puts response.read_body{
"sms_consent": {
"opted_in": true,
"phone": "+14155552671"
},
"meta": {
"request_id": "6f1c2a9e-3b7d-4e58-9a21-c4d8e0b7f312",
"timestamp": "2026-10-12T15:22:08Z"
}
}{
"message": "<string>"
}{
"error_message": "<string>",
"errors": "<string>",
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"code": "<string>",
"payment_uuid": "<string>",
"error_details": [
{
"code": "<string>",
"field": "<string>",
"payment": "not_attempted",
"message": "<string>"
}
],
"coded_recovery": true
}
}{
"error_message": "Only US and Canadian phone numbers can receive subscription texts",
"error_code": "unsupported_phone_country",
"errors": {},
"meta": {
"request_id": "6f1c2a9e-3b7d-4e58-9a21-c4d8e0b7f312",
"timestamp": "2026-10-12T15:22:08Z"
}
}Authorizations
Bearer token authentication
Path Parameters
Subscription token
Body
Whether the customer agrees to receive recurring subscription texts.
The phone number to text, in any format a customer types. Only US and Canadian numbers are accepted.
The version of the disclosure the customer saw, from the GET on the same path.
curl --request PUT \
--url https://api.fluid.app/api/checkout/v2026-04/subscriptions/{token}/sms-consent \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"opted_in": true,
"phone": "(415) 555-2671",
"disclosure_version": "2026-10-draft-1"
}
'import requests
url = "https://api.fluid.app/api/checkout/v2026-04/subscriptions/{token}/sms-consent"
payload = {
"opted_in": True,
"phone": "(415) 555-2671",
"disclosure_version": "2026-10-draft-1"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({opted_in: true, phone: '(415) 555-2671', disclosure_version: '2026-10-draft-1'})
};
fetch('https://api.fluid.app/api/checkout/v2026-04/subscriptions/{token}/sms-consent', 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/checkout/v2026-04/subscriptions/{token}/sms-consent",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'opted_in' => true,
'phone' => '(415) 555-2671',
'disclosure_version' => '2026-10-draft-1'
]),
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/checkout/v2026-04/subscriptions/{token}/sms-consent"
payload := strings.NewReader("{\n \"opted_in\": true,\n \"phone\": \"(415) 555-2671\",\n \"disclosure_version\": \"2026-10-draft-1\"\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.fluid.app/api/checkout/v2026-04/subscriptions/{token}/sms-consent")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"opted_in\": true,\n \"phone\": \"(415) 555-2671\",\n \"disclosure_version\": \"2026-10-draft-1\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/checkout/v2026-04/subscriptions/{token}/sms-consent")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"opted_in\": true,\n \"phone\": \"(415) 555-2671\",\n \"disclosure_version\": \"2026-10-draft-1\"\n}"
response = http.request(request)
puts response.read_body{
"sms_consent": {
"opted_in": true,
"phone": "+14155552671"
},
"meta": {
"request_id": "6f1c2a9e-3b7d-4e58-9a21-c4d8e0b7f312",
"timestamp": "2026-10-12T15:22:08Z"
}
}{
"message": "<string>"
}{
"error_message": "<string>",
"errors": "<string>",
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"code": "<string>",
"payment_uuid": "<string>",
"error_details": [
{
"code": "<string>",
"field": "<string>",
"payment": "not_attempted",
"message": "<string>"
}
],
"coded_recovery": true
}
}{
"error_message": "Only US and Canadian phone numbers can receive subscription texts",
"error_code": "unsupported_phone_country",
"errors": {},
"meta": {
"request_id": "6f1c2a9e-3b7d-4e58-9a21-c4d8e0b7f312",
"timestamp": "2026-10-12T15:22:08Z"
}
}