curl --request POST \
--url https://core.api.dev.predictstreet.sde.adifoundation.ai/api/me/redemptions \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <api-key>' \
--data '
{
"marketId": "PM-WC26-R16-USA-WC26-1910V2"
}
'import requests
url = "https://core.api.dev.predictstreet.sde.adifoundation.ai/api/me/redemptions"
payload = { "marketId": "PM-WC26-R16-USA-WC26-1910V2" }
headers = {
"X-Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({marketId: 'PM-WC26-R16-USA-WC26-1910V2'})
};
fetch('https://core.api.dev.predictstreet.sde.adifoundation.ai/api/me/redemptions', 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://core.api.dev.predictstreet.sde.adifoundation.ai/api/me/redemptions",
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([
'marketId' => 'PM-WC26-R16-USA-WC26-1910V2'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <api-key>"
],
]);
$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://core.api.dev.predictstreet.sde.adifoundation.ai/api/me/redemptions"
payload := strings.NewReader("{\n \"marketId\": \"PM-WC26-R16-USA-WC26-1910V2\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Api-Key", "<api-key>")
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://core.api.dev.predictstreet.sde.adifoundation.ai/api/me/redemptions")
.header("X-Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"marketId\": \"PM-WC26-R16-USA-WC26-1910V2\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://core.api.dev.predictstreet.sde.adifoundation.ai/api/me/redemptions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"marketId\": \"PM-WC26-R16-USA-WC26-1910V2\"\n}"
response = http.request(request)
puts response.read_body{
"status": 404,
"error": {
"code": "<string>",
"message": "<string>",
"trace_id": "<string>",
"retryAfterSec": 123,
"retryable": true,
"details": {}
}
}{
"status": 404,
"error": {
"code": "<string>",
"message": "<string>",
"trace_id": "<string>",
"retryAfterSec": 123,
"retryable": true,
"details": {}
}
}{
"status": 404,
"error": {
"code": "<string>",
"message": "<string>",
"trace_id": "<string>",
"retryAfterSec": 123,
"retryable": true,
"details": {}
}
}{
"status": 404,
"error": {
"code": "<string>",
"message": "<string>",
"trace_id": "<string>",
"retryAfterSec": 123,
"retryable": true,
"details": {}
}
}{
"status": 400,
"error": {
"code": "bad_request",
"message": "<string>",
"trace_id": "<string>",
"retryAfterSec": 123,
"retryable": true,
"details": {}
}
}Co-sign a redeem (not available yet)
Not available yet: a request that passes authentication and validation is answered 503 redeem_not_yet_enabled. To claim a resolved position, use POST /api/me/positions/redeem and poll GET /api/me/positions/redeem/{jobId}.
curl --request POST \
--url https://core.api.dev.predictstreet.sde.adifoundation.ai/api/me/redemptions \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <api-key>' \
--data '
{
"marketId": "PM-WC26-R16-USA-WC26-1910V2"
}
'import requests
url = "https://core.api.dev.predictstreet.sde.adifoundation.ai/api/me/redemptions"
payload = { "marketId": "PM-WC26-R16-USA-WC26-1910V2" }
headers = {
"X-Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({marketId: 'PM-WC26-R16-USA-WC26-1910V2'})
};
fetch('https://core.api.dev.predictstreet.sde.adifoundation.ai/api/me/redemptions', 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://core.api.dev.predictstreet.sde.adifoundation.ai/api/me/redemptions",
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([
'marketId' => 'PM-WC26-R16-USA-WC26-1910V2'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <api-key>"
],
]);
$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://core.api.dev.predictstreet.sde.adifoundation.ai/api/me/redemptions"
payload := strings.NewReader("{\n \"marketId\": \"PM-WC26-R16-USA-WC26-1910V2\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Api-Key", "<api-key>")
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://core.api.dev.predictstreet.sde.adifoundation.ai/api/me/redemptions")
.header("X-Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"marketId\": \"PM-WC26-R16-USA-WC26-1910V2\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://core.api.dev.predictstreet.sde.adifoundation.ai/api/me/redemptions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"marketId\": \"PM-WC26-R16-USA-WC26-1910V2\"\n}"
response = http.request(request)
puts response.read_body{
"status": 404,
"error": {
"code": "<string>",
"message": "<string>",
"trace_id": "<string>",
"retryAfterSec": 123,
"retryable": true,
"details": {}
}
}{
"status": 404,
"error": {
"code": "<string>",
"message": "<string>",
"trace_id": "<string>",
"retryAfterSec": 123,
"retryable": true,
"details": {}
}
}{
"status": 404,
"error": {
"code": "<string>",
"message": "<string>",
"trace_id": "<string>",
"retryAfterSec": 123,
"retryable": true,
"details": {}
}
}{
"status": 404,
"error": {
"code": "<string>",
"message": "<string>",
"trace_id": "<string>",
"retryAfterSec": 123,
"retryable": true,
"details": {}
}
}{
"status": 400,
"error": {
"code": "bad_request",
"message": "<string>",
"trace_id": "<string>",
"retryAfterSec": 123,
"retryable": true,
"details": {}
}
}Authorizations
Partner / integrator key — format ps_live_<keyId>_<secret>. Partner keys are issued by PredictStreet; a user can also create keys bound to their own wallet from their account settings in the web app. Never ship to a browser. multi_wallet partners must additionally send X-User-Wallet: 0x<40-hex> on every authenticated request to declare the acting wallet. See the API keys guide for scope taxonomy, partner kinds, rate limits, and rotation procedure.
Headers
Optional. Requests carrying the same key replay the original operation instead of creating a new one. When omitted, the key is derived from the wallet, the operation and the exact request body, so a byte-identical repeat replays the first operation — send your own key to run the same operation twice.
Required for multi_wallet partners on every authenticated request; ignored for single_wallet. Declares the acting end-user wallet for this request — drives KYC checks, balances/positions/orders attribution, rate-limit buckets, and audit. Lower-cased server-side. Missing on a multi_wallet key → 401 api_key_user_wallet_required; malformed → 401 api_key_user_wallet_invalid. The on-chain CTFExchange/Vault contracts still verify EIP-712 signer ↔ vault binding, so loosening API-layer attribution is safe by construction.
^0x[a-fA-F0-9]{40}$"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb3"
Body
Market identifier — accepts the symbol or the bytes32 conditionId. Server resolves to the canonical conditionId before signing. The underlying chain call (ConditionalTokens.redeemPositions) doesn't take an explicit amount — REDEEM consumes the full position the user holds across every outcome of the market.
"PM-WC26-R16-USA-WC26-1910V2"