Restreaming API
Send a live stream on to up to five other services that take RTMP or RTMPS, at the same time. Each destination is billed per destination-hour while it is live.
This page is generated from the OpenAPI specification; the same text is inMarkdown for tools and AI assistants.
List a stream's destinations
GET/v1/streams/{playback_id}/destinations
The services a stream is sent on to, and how each is doing. Stream keys are never returned, only their last characters.
Path parameters
| Name | Type | Description |
|---|---|---|
| playback_idrequired | string | The stream’s |
Response 200
The destinations.
Fields
| Name | Type | Description |
|---|---|---|
| destinationsrequired | array of object | |
| destinations[].idrequired | string (uuid) | |
| destinations[].namerequired | string | |
| destinations[].urlrequired | string | |
| destinations[].stream_key_hintrequired | string | The last characters of the stream key. |
| destinations[].enabledrequired | boolean | |
| destinations[].statusrequired | string | One of |
| destinations[].last_errorrequired | string or null | |
| destinations[].status_updated_atrequired | string (date-time) or null | |
| destinations[].created_atrequired | string (date-time) | |
| destinations[].updated_atrequired | string (date-time) | |
| max_destinationsrequired | integer | How many destinations a stream may have. |
Errors
| Status | Code | Meaning |
|---|---|---|
| 404 | not_found | No such stream in your organization. |
curl "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations" \ -H "Authorization: Bearer $CARDINAL_API_KEY"import os
import requests
response = requests.get( "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations", headers={ "Authorization": f"Bearer {os.environ['CARDINAL_API_KEY']}", }, timeout=30,)print(response.status_code, response.text)const response = await fetch('https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations', { method: 'GET', headers: { Authorization: `Bearer ${process.env.CARDINAL_API_KEY}`, },});const data = await response.json();console.log(response.status, data);const response: Response = await fetch('https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations', { method: 'GET', headers: { Authorization: `Bearer ${process.env.CARDINAL_API_KEY}`, },});const data: unknown = await response.json();console.log(response.status, data);<?phprequire 'vendor/autoload.php'; // composer require guzzlehttp/guzzle
$client = new GuzzleHttp\Client();$response = $client->request('GET', 'https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations', [ 'headers' => [ 'Authorization' => 'Bearer ' . getenv('CARDINAL_API_KEY'), ], 'http_errors' => false,]);echo $response->getStatusCode(), ' ', $response->getBody(), PHP_EOL;require 'json'require 'net/http'
uri = URI("https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations")request = Net::HTTP::Get.new(uri)request['Authorization'] = "Bearer #{ENV.fetch('CARDINAL_API_KEY')}"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }puts response.code, response.bodypackage main
import ( "fmt" "io" "net/http" "os")
func main() { req, err := http.NewRequest("GET", "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations", nil) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer "+os.Getenv("CARDINAL_API_KEY"))
resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() data, _ := io.ReadAll(resp.Body) fmt.Println(resp.StatusCode, string(data))}import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;
public class Example { public static void main(String[] args) throws Exception { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations")) .header("Authorization", "Bearer " + System.getenv("CARDINAL_API_KEY")) .method("GET", HttpRequest.BodyPublishers.noBody()) .build(); HttpResponse<String> response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode() + " " + response.body()); }}using System.Net.Http.Headers;using System.Text;
using var client = new HttpClient();using var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations");request.Headers.Authorization = new AuthenticationHeaderValue( "Bearer", Environment.GetEnvironmentVariable("CARDINAL_API_KEY"));
using var response = await client.SendAsync(request);Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");{ "destinations": [ { "id": "3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83", "name": "Our channel", "url": "rtmps://live.example.com:443/app", "stream_key_hint": "...mnop", "enabled": true, "status": "idle", "last_error": null, "status_updated_at": null, "created_at": "2026-10-18T14:40:00Z", "updated_at": "2026-10-18T14:40:00Z" } ], "max_destinations": 5}Add a destination
POST/v1/streams/{playback_id}/destinations
Sends the stream on to another service while it is live. Give the server URL and stream key the service shows you. The key is stored encrypted, never returned, and deleted an hour after the broadcast ends. Destinations on private networks, or Cardinal’s own ingest, are refused.
Path parameters
| Name | Type | Description |
|---|---|---|
| playback_idrequired | string | The stream’s |
Request body
| Name | Type | Description |
|---|---|---|
| namerequired | string | Shown to everyone who can see the stream. |
| urlrequired | string | The service’s server URL: |
| stream_keyrequired | string | |
| enabled | boolean | Default true. |
Response 201
The destination.
Fields
| Name | Type | Description |
|---|---|---|
| idrequired | string (uuid) | |
| namerequired | string | |
| urlrequired | string | |
| stream_key_hintrequired | string | The last characters of the stream key. |
| enabledrequired | boolean | |
| statusrequired | string | One of |
| last_errorrequired | string or null | |
| status_updated_atrequired | string (date-time) or null | |
| created_atrequired | string (date-time) | |
| updated_atrequired | string (date-time) |
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_body | The body is not a JSON object. |
| 400 | missing_field |
|
| 400 | invalid_name | The name is not 1-80 visible characters, or contains the stream key. |
| 400 | invalid_url | The URL is not an |
| 400 | invalid_stream_key | The stream key is empty, too long, or has characters a stream key cannot. |
| 400 | destination_unresolvable | The server name could not be found. |
| 400 | destination_not_allowed | That server address cannot be used. |
| 404 | not_found | No such stream in your organization. |
| 409 | stream_ended | The stream has ended. |
| 409 | destination_limit | The stream already has the most destinations allowed. |
| 503 | restream_unconfigured | Restreaming is not available on this deployment. |
| 503 | restream_unpriced | Restreaming is not available for this broadcast. |
curl -X POST "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations" \ -H "Authorization: Bearer $CARDINAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Our channel", "url": "rtmps://live.example.com:443/app", "stream_key": "abcd-efgh-ijkl-mnop", "enabled": true}'import os
import requests
response = requests.post( "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations", headers={ "Authorization": f"Bearer {os.environ['CARDINAL_API_KEY']}", }, json={ "name": "Our channel", "url": "rtmps://live.example.com:443/app", "stream_key": "abcd-efgh-ijkl-mnop", "enabled": True, }, timeout=30,)print(response.status_code, response.text)const response = await fetch('https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations', { method: 'POST', headers: { Authorization: `Bearer ${process.env.CARDINAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "name": "Our channel", "url": "rtmps://live.example.com:443/app", "stream_key": "abcd-efgh-ijkl-mnop", "enabled": true }),});const data = await response.json();console.log(response.status, data);const response: Response = await fetch('https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations', { method: 'POST', headers: { Authorization: `Bearer ${process.env.CARDINAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "name": "Our channel", "url": "rtmps://live.example.com:443/app", "stream_key": "abcd-efgh-ijkl-mnop", "enabled": true }),});const data: unknown = await response.json();console.log(response.status, data);<?phprequire 'vendor/autoload.php'; // composer require guzzlehttp/guzzle
$client = new GuzzleHttp\Client();$response = $client->request('POST', 'https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations', [ 'headers' => [ 'Authorization' => 'Bearer ' . getenv('CARDINAL_API_KEY'), ], 'json' => [ 'name' => 'Our channel', 'url' => 'rtmps://live.example.com:443/app', 'stream_key' => 'abcd-efgh-ijkl-mnop', 'enabled' => true, ], 'http_errors' => false,]);echo $response->getStatusCode(), ' ', $response->getBody(), PHP_EOL;require 'json'require 'net/http'
uri = URI("https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations")request = Net::HTTP::Post.new(uri)request['Authorization'] = "Bearer #{ENV.fetch('CARDINAL_API_KEY')}"request['Content-Type'] = 'application/json'request.body = JSON.generate({ "name" => "Our channel", "url" => "rtmps://live.example.com:443/app", "stream_key" => "abcd-efgh-ijkl-mnop", "enabled" => true})
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }puts response.code, response.bodypackage main
import ( "fmt" "io" "net/http" "os" "strings")
func main() { req, err := http.NewRequest("POST", "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations", strings.NewReader(`{ "name": "Our channel", "url": "rtmps://live.example.com:443/app", "stream_key": "abcd-efgh-ijkl-mnop", "enabled": true}`)) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer "+os.Getenv("CARDINAL_API_KEY")) req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() data, _ := io.ReadAll(resp.Body) fmt.Println(resp.StatusCode, string(data))}import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;
public class Example { public static void main(String[] args) throws Exception { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations")) .header("Authorization", "Bearer " + System.getenv("CARDINAL_API_KEY")) .header("Content-Type", "application/json") .method("POST", HttpRequest.BodyPublishers.ofString("{\"name\":\"Our channel\",\"url\":\"rtmps://live.example.com:443/app\",\"stream_key\":\"abcd-efgh-ijkl-mnop\",\"enabled\":true}")) .build(); HttpResponse<String> response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode() + " " + response.body()); }}using System.Net.Http.Headers;using System.Text;
using var client = new HttpClient();using var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations");request.Headers.Authorization = new AuthenticationHeaderValue( "Bearer", Environment.GetEnvironmentVariable("CARDINAL_API_KEY"));request.Content = new StringContent("{\"name\":\"Our channel\",\"url\":\"rtmps://live.example.com:443/app\",\"stream_key\":\"abcd-efgh-ijkl-mnop\",\"enabled\":true}", Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");{ "id": "3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83", "name": "Our channel", "url": "rtmps://live.example.com:443/app", "stream_key_hint": "...mnop", "enabled": true, "status": "idle", "last_error": null, "status_updated_at": null, "created_at": "2026-10-18T14:40:00Z", "updated_at": "2026-10-18T14:40:00Z"}Pause, resume or rename a destination
PATCH/v1/streams/{playback_id}/destinations/{destination_id}
Path parameters
| Name | Type | Description |
|---|---|---|
| playback_idrequired | string | The stream’s |
| destination_idrequired | string (uuid) | The destination’s |
Request body
| Name | Type | Description |
|---|---|---|
| enabled | boolean | |
| name | string |
Response 200
The destination as it now is.
Fields
| Name | Type | Description |
|---|---|---|
| idrequired | string (uuid) | |
| namerequired | string | |
| urlrequired | string | |
| stream_key_hintrequired | string | The last characters of the stream key. |
| enabledrequired | boolean | |
| statusrequired | string | One of |
| last_errorrequired | string or null | |
| status_updated_atrequired | string (date-time) or null | |
| created_atrequired | string (date-time) | |
| updated_atrequired | string (date-time) |
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_body | The body is not a JSON object. |
| 400 | missing_field | Neither |
| 400 | invalid_name | The name is not 1-80 visible characters, or contains the stream key. |
| 404 | not_found | No such stream or destination in your organization. |
curl -X PATCH "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83" \ -H "Authorization: Bearer $CARDINAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "enabled": false}'import os
import requests
response = requests.patch( "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83", headers={ "Authorization": f"Bearer {os.environ['CARDINAL_API_KEY']}", }, json={ "enabled": False, }, timeout=30,)print(response.status_code, response.text)const response = await fetch('https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83', { method: 'PATCH', headers: { Authorization: `Bearer ${process.env.CARDINAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "enabled": false }),});const data = await response.json();console.log(response.status, data);const response: Response = await fetch('https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83', { method: 'PATCH', headers: { Authorization: `Bearer ${process.env.CARDINAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "enabled": false }),});const data: unknown = await response.json();console.log(response.status, data);<?phprequire 'vendor/autoload.php'; // composer require guzzlehttp/guzzle
$client = new GuzzleHttp\Client();$response = $client->request('PATCH', 'https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83', [ 'headers' => [ 'Authorization' => 'Bearer ' . getenv('CARDINAL_API_KEY'), ], 'json' => [ 'enabled' => false, ], 'http_errors' => false,]);echo $response->getStatusCode(), ' ', $response->getBody(), PHP_EOL;require 'json'require 'net/http'
uri = URI("https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83")request = Net::HTTP::Patch.new(uri)request['Authorization'] = "Bearer #{ENV.fetch('CARDINAL_API_KEY')}"request['Content-Type'] = 'application/json'request.body = JSON.generate({ "enabled" => false})
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }puts response.code, response.bodypackage main
import ( "fmt" "io" "net/http" "os" "strings")
func main() { req, err := http.NewRequest("PATCH", "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83", strings.NewReader(`{ "enabled": false}`)) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer "+os.Getenv("CARDINAL_API_KEY")) req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() data, _ := io.ReadAll(resp.Body) fmt.Println(resp.StatusCode, string(data))}import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;
public class Example { public static void main(String[] args) throws Exception { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83")) .header("Authorization", "Bearer " + System.getenv("CARDINAL_API_KEY")) .header("Content-Type", "application/json") .method("PATCH", HttpRequest.BodyPublishers.ofString("{\"enabled\":false}")) .build(); HttpResponse<String> response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode() + " " + response.body()); }}using System.Net.Http.Headers;using System.Text;
using var client = new HttpClient();using var request = new HttpRequestMessage(new HttpMethod("PATCH"), "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83");request.Headers.Authorization = new AuthenticationHeaderValue( "Bearer", Environment.GetEnvironmentVariable("CARDINAL_API_KEY"));request.Content = new StringContent("{\"enabled\":false}", Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");Remove a destination
DELETE/v1/streams/{playback_id}/destinations/{destination_id}
Path parameters
| Name | Type | Description |
|---|---|---|
| playback_idrequired | string | The stream’s |
| destination_idrequired | string (uuid) | The destination’s |
Response 204
Removed.
Errors
| Status | Code | Meaning |
|---|---|---|
| 404 | not_found | No such stream or destination in your organization. |
curl -X DELETE "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83" \ -H "Authorization: Bearer $CARDINAL_API_KEY"import os
import requests
response = requests.delete( "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83", headers={ "Authorization": f"Bearer {os.environ['CARDINAL_API_KEY']}", }, timeout=30,)print(response.status_code, response.text)const response = await fetch('https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83', { method: 'DELETE', headers: { Authorization: `Bearer ${process.env.CARDINAL_API_KEY}`, },});const data = await response.json();console.log(response.status, data);const response: Response = await fetch('https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83', { method: 'DELETE', headers: { Authorization: `Bearer ${process.env.CARDINAL_API_KEY}`, },});const data: unknown = await response.json();console.log(response.status, data);<?phprequire 'vendor/autoload.php'; // composer require guzzlehttp/guzzle
$client = new GuzzleHttp\Client();$response = $client->request('DELETE', 'https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83', [ 'headers' => [ 'Authorization' => 'Bearer ' . getenv('CARDINAL_API_KEY'), ], 'http_errors' => false,]);echo $response->getStatusCode(), ' ', $response->getBody(), PHP_EOL;require 'json'require 'net/http'
uri = URI("https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83")request = Net::HTTP::Delete.new(uri)request['Authorization'] = "Bearer #{ENV.fetch('CARDINAL_API_KEY')}"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }puts response.code, response.bodypackage main
import ( "fmt" "io" "net/http" "os")
func main() { req, err := http.NewRequest("DELETE", "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83", nil) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer "+os.Getenv("CARDINAL_API_KEY"))
resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() data, _ := io.ReadAll(resp.Body) fmt.Println(resp.StatusCode, string(data))}import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;
public class Example { public static void main(String[] args) throws Exception { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83")) .header("Authorization", "Bearer " + System.getenv("CARDINAL_API_KEY")) .method("DELETE", HttpRequest.BodyPublishers.noBody()) .build(); HttpResponse<String> response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode() + " " + response.body()); }}using System.Net.Http.Headers;using System.Text;
using var client = new HttpClient();using var request = new HttpRequestMessage(new HttpMethod("DELETE"), "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/destinations/3b4f9c2e-8d1a-4f6b-a2c7-9e5d1b0f4a83");request.Headers.Authorization = new AuthenticationHeaderValue( "Bearer", Environment.GetEnvironmentVariable("CARDINAL_API_KEY"));
using var response = await client.SendAsync(request);Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");