curl --request GET \
--url https://api.openagent.to/api/v1/investors/{id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.openagent.to/api/v1/investors/{id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.openagent.to/api/v1/investors/{id}', 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.openagent.to/api/v1/investors/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.openagent.to/api/v1/investors/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.openagent.to/api/v1/investors/{id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.openagent.to/api/v1/investors/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {
"investor": {
"_id": "bbb000000000000000000001",
"addressLine1": "123 Main Street",
"city": "San Francisco",
"country": "US",
"createdAt": "2026-09-01T09:15:32.104Z",
"dateOfBirth": null,
"dateOfDeath": null,
"email": "john.doe@example.com",
"entityType": null,
"externalId": "ext-seed-john-doe",
"investorStatus": "active",
"issuerIds": [],
"jurisdiction": "US-CA",
"lastSearchAttemptAt": null,
"legalName": "John Doe",
"lostHolderDate": null,
"lostReason": null,
"lostStatusFlag": false,
"phone": null,
"preferredContactMethod": "mail",
"registrationName": null,
"registrationType": "individual",
"securityIds": [],
"state": "CA",
"taxFormOnFile": "W-9",
"taxId": "000-00-0000",
"updatedAt": "2026-09-01T09:15:32.104Z",
"updatedBy": null,
"uuid": "7ff8b078-68a7-4b44-9435-5cfce41ef9a5",
"zip": "94105"
},
"kycs": [
{
"_id": "507f1f77bcf86cd799439031",
"addressLastConfirmedAt": null,
"addressLine1": "123 Main Street",
"addressLine2": null,
"approvedAt": null,
"approvedBy": null,
"backupWithholdingRequired": false,
"city": "San Francisco",
"country": "US",
"createdAt": "2026-09-01T09:15:32.104Z",
"expiresAt": null,
"investorId": "bbb000000000000000000001",
"issuerId": "aaa000000000000000000001",
"issuerName": "Acme Tokenization LLC",
"jurisdiction": "US-CA",
"mailingAddressSameAsReg": true,
"securityId": "ccc000000000000000000001",
"securityName": "Seed Preferred Equity",
"state": "CA",
"status": "approved",
"submittedAt": "2026-09-01T09:15:32.104Z",
"taxCertExpiryAt": null,
"taxFormOnFile": "W-9",
"updatedAt": "2026-09-01T09:15:32.104Z",
"updatedBy": null,
"uuid": "94f1594e-2c56-43ee-aaeb-ab0584c415a7",
"zip": "94105"
}
]
},
"message": "Success",
"meta": {
"timestamp": "2026-09-01T09:15:32.104Z",
"requestId": "3f1c9d2e-6b7a-4f18-9c53-0a2b6d4e8f10"
},
"statusCode": 200,
"success": true
}{
"error": {
"code": "Validation error",
"details": [
{
"field": "email",
"message": "Invalid email format",
"allowedValues": [
"<string>"
]
}
]
},
"message": "Validation error",
"meta": {
"timestamp": "2026-09-01T09:15:32.104Z",
"requestId": "3f1c9d2e-6b7a-4f18-9c53-0a2b6d4e8f10"
},
"statusCode": 422,
"success": false
}{
"error": {
"code": "Validation error",
"details": [
{
"field": "email",
"message": "Invalid email format",
"allowedValues": [
"<string>"
]
}
]
},
"message": "Validation error",
"meta": {
"timestamp": "2026-09-01T09:15:32.104Z",
"requestId": "3f1c9d2e-6b7a-4f18-9c53-0a2b6d4e8f10"
},
"statusCode": 422,
"success": false
}{
"data": "<unknown>",
"message": "Success",
"meta": {
"timestamp": "2026-09-01T09:15:32.104Z",
"requestId": "3f1c9d2e-6b7a-4f18-9c53-0a2b6d4e8f10"
},
"statusCode": 404,
"success": false
}{
"error": {
"code": "Validation error",
"details": [
{
"field": "email",
"message": "Invalid email format",
"allowedValues": [
"<string>"
]
}
]
},
"message": "Validation error",
"meta": {
"timestamp": "2026-09-01T09:15:32.104Z",
"requestId": "3f1c9d2e-6b7a-4f18-9c53-0a2b6d4e8f10"
},
"statusCode": 422,
"success": false
}{
"error": {
"code": "Validation error",
"details": [
{
"field": "email",
"message": "Invalid email format",
"allowedValues": [
"<string>"
]
}
]
},
"message": "Validation error",
"meta": {
"timestamp": "2026-09-01T09:15:32.104Z",
"requestId": "3f1c9d2e-6b7a-4f18-9c53-0a2b6d4e8f10"
},
"statusCode": 422,
"success": false
}Get one investor
Returns the full investor record — including PII: an unmasked taxId, date of birth, postal address, email and phone — under an investor key, alongside its KYC records. securityId changes which key carries the KYC data. Without it you get a kycs array; with it you get a single kyc record for that security, which is null when the investor has no such record or when that security belongs to another issuer. Both KYC paths are scoped to the caller’s issuer. For an issuer_admin the kycs array holds only records for its own issuer’s securities, so an investor holding securities from several issuers yields a shorter array than a ta_admin sees. issuerId narrows that array further and only ever narrows: an issuer_admin naming another issuer gets an empty array, never that issuer’s records. It is ignored when securityId is given. An issuer_admin asking for an investor with no relationship to its issuer gets 404, not 403 — a 403 would confirm the investor exists. Requires investor:read.
curl --request GET \
--url https://api.openagent.to/api/v1/investors/{id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.openagent.to/api/v1/investors/{id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.openagent.to/api/v1/investors/{id}', 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.openagent.to/api/v1/investors/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.openagent.to/api/v1/investors/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.openagent.to/api/v1/investors/{id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.openagent.to/api/v1/investors/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {
"investor": {
"_id": "bbb000000000000000000001",
"addressLine1": "123 Main Street",
"city": "San Francisco",
"country": "US",
"createdAt": "2026-09-01T09:15:32.104Z",
"dateOfBirth": null,
"dateOfDeath": null,
"email": "john.doe@example.com",
"entityType": null,
"externalId": "ext-seed-john-doe",
"investorStatus": "active",
"issuerIds": [],
"jurisdiction": "US-CA",
"lastSearchAttemptAt": null,
"legalName": "John Doe",
"lostHolderDate": null,
"lostReason": null,
"lostStatusFlag": false,
"phone": null,
"preferredContactMethod": "mail",
"registrationName": null,
"registrationType": "individual",
"securityIds": [],
"state": "CA",
"taxFormOnFile": "W-9",
"taxId": "000-00-0000",
"updatedAt": "2026-09-01T09:15:32.104Z",
"updatedBy": null,
"uuid": "7ff8b078-68a7-4b44-9435-5cfce41ef9a5",
"zip": "94105"
},
"kycs": [
{
"_id": "507f1f77bcf86cd799439031",
"addressLastConfirmedAt": null,
"addressLine1": "123 Main Street",
"addressLine2": null,
"approvedAt": null,
"approvedBy": null,
"backupWithholdingRequired": false,
"city": "San Francisco",
"country": "US",
"createdAt": "2026-09-01T09:15:32.104Z",
"expiresAt": null,
"investorId": "bbb000000000000000000001",
"issuerId": "aaa000000000000000000001",
"issuerName": "Acme Tokenization LLC",
"jurisdiction": "US-CA",
"mailingAddressSameAsReg": true,
"securityId": "ccc000000000000000000001",
"securityName": "Seed Preferred Equity",
"state": "CA",
"status": "approved",
"submittedAt": "2026-09-01T09:15:32.104Z",
"taxCertExpiryAt": null,
"taxFormOnFile": "W-9",
"updatedAt": "2026-09-01T09:15:32.104Z",
"updatedBy": null,
"uuid": "94f1594e-2c56-43ee-aaeb-ab0584c415a7",
"zip": "94105"
}
]
},
"message": "Success",
"meta": {
"timestamp": "2026-09-01T09:15:32.104Z",
"requestId": "3f1c9d2e-6b7a-4f18-9c53-0a2b6d4e8f10"
},
"statusCode": 200,
"success": true
}{
"error": {
"code": "Validation error",
"details": [
{
"field": "email",
"message": "Invalid email format",
"allowedValues": [
"<string>"
]
}
]
},
"message": "Validation error",
"meta": {
"timestamp": "2026-09-01T09:15:32.104Z",
"requestId": "3f1c9d2e-6b7a-4f18-9c53-0a2b6d4e8f10"
},
"statusCode": 422,
"success": false
}{
"error": {
"code": "Validation error",
"details": [
{
"field": "email",
"message": "Invalid email format",
"allowedValues": [
"<string>"
]
}
]
},
"message": "Validation error",
"meta": {
"timestamp": "2026-09-01T09:15:32.104Z",
"requestId": "3f1c9d2e-6b7a-4f18-9c53-0a2b6d4e8f10"
},
"statusCode": 422,
"success": false
}{
"data": "<unknown>",
"message": "Success",
"meta": {
"timestamp": "2026-09-01T09:15:32.104Z",
"requestId": "3f1c9d2e-6b7a-4f18-9c53-0a2b6d4e8f10"
},
"statusCode": 404,
"success": false
}{
"error": {
"code": "Validation error",
"details": [
{
"field": "email",
"message": "Invalid email format",
"allowedValues": [
"<string>"
]
}
]
},
"message": "Validation error",
"meta": {
"timestamp": "2026-09-01T09:15:32.104Z",
"requestId": "3f1c9d2e-6b7a-4f18-9c53-0a2b6d4e8f10"
},
"statusCode": 422,
"success": false
}{
"error": {
"code": "Validation error",
"details": [
{
"field": "email",
"message": "Invalid email format",
"allowedValues": [
"<string>"
]
}
]
},
"message": "Validation error",
"meta": {
"timestamp": "2026-09-01T09:15:32.104Z",
"requestId": "3f1c9d2e-6b7a-4f18-9c53-0a2b6d4e8f10"
},
"statusCode": 422,
"success": false
}Authorizations
Staff access token. Sent as Authorization: Bearer <token>, or — when that header is absent — read from the accessToken cookie, which is how the admin app authenticates. Tokens carry a tokenVersion; logout and password reset bump it, revoking every outstanding token for that account.
Path Parameters
^[a-f\d]{24}$Query Parameters
Return a single focused KYC record for this security under kyc instead of the kycs array. The two are mutually exclusive keys in the response.
^[a-f\d]{24}$Narrow the kycs array to one issuer. Ignored when securityId is given, since that path returns a single record.
^[a-f\d]{24}$Response
The investor with its KYC records — kycs as an array, or a single kyc when securityId was given.

