API Documentation
Introduction
Welcome to the ShadowSelf API documentation. We are pleased to offer programmatic access to the core functionalities of the ShadowSelf platform, allowing developers and users to integrate our synthetic identity management tools directly into their own applications, workflows, and systems.
This API is designed following RESTful principles, ensuring predictability, ease of use, and compatibility with standard HTTP
practices. You can expect to interact with it using conventional HTTP methods (GET
, POST
, PUT
, DELETE
, etc.), receive standard HTTP status codes indicating success or failure, and exchange data primarily in JSON
format. Our goal is to provide an API that feels familiar and adheres to the best practices commonly found across modern web
services, facilitating a smooth integration experience for developers of all skill levels.
ShadowSelf API base URL: https://shadowself.io/api
Whether you are looking to automate identity management, build custom tools on top of our platform, or simply prefer interacting via code, this API provides the necessary endpoints and functionalities.
Purpose
The primary purpose of the ShadowSelf API is to give users programmatic control over their synthetic identities. While our web-based dashboard provides a user-friendly interface for managing personas, we understand the need for automation, integration, and more advanced control that only an API can offer.
Here are key objectives of this API include:
- Automation: Automate tasks like sending emails, replies to SMS, or interacting with third-party APIs.
- Integration: Facilitate the seamless integration of ShadowSelf's capabilities into third-party applications, custom scripts, or specialized tools.
- Programmatic Management: Create, retrieve, update, and delete synthetic identities associated attributes (like phone numbers, emails, etc.) directly through code, bypassing the manual dashboard interface.
- Flexibility and Openness: Offer developers the flexibility to build custom solutions tailored to their specific needs, fostering innovation and extending the utility of the ShadowSelf platform. We believe in openness and providing the tools necessary for users to interact with our service in the way that best suits them.
Essentially, the API serves as an alternative and complementary way to interact with your ShadowSelf account, designed for efficiency, automation, and custom integrations.
Use Cases
The ShadowSelf API opens up a variety of possibilities for developers and advanced users. Here are a few concrete examples illustrating how you might leverage the API:
- Real-time Event Monitoring: Utilize potential WebSocket connections to listen for specific events related to your identities. For instance, you could build a notification system that alerts you immediately when a new message is received on one of your synthetic phone numbers or email addresses.
- Custom Email/Messaging Client: Develop your own specialized client application to manage communications associated with your ShadowSelf email addresses. This could offer a tailored user interface, advanced filtering capabilities, or integration with other communication tools, providing a more powerful alternative to generic clients or the web dashboard.
- Extending Account Management: The API enables you to build custom tools to manage these stored credentials programmatically. You could, for example, create scripts for bulk importing/exporting credentials, integrating with other secret management systems, adding new fields or developing custom interfaces for accessing this stored login data beyond our standard dashboard.
These are just illustrative examples. The API provides the building blocks for you to create innovative solutions tailored to your privacy, security, or automation needs.
Considerations
As you utilize the ShadowSelf API, please be mindful that the platform is maintained with limited resources. We ask that you interact with the API responsibly by avoiding spamming requests or implementing overly aggressive polling, ensuring your integrations are efficient to minimize server load.
Currently, we operate on a principle of mutual respect and trust, foregoing strict rate limits. We trust our users to use the API fairly, allowing us to maintain an open environment. However, please understand that we reserve the right to implement limits or block traffic if necessary to protect service stability for everyone. Your considerate usage helps us keep the API accessible.
Feedback and Contributions
We are continuously looking to improve and expand the ShadowSelf API. If you:
- Feel an important section or piece of information is missing from this documentation.
- Have suggestions for new API routes or features.
- Discover a bug or unexpected behavior.
- Have any other feedback.
Please reach out to us! You can contact us via our contact page or, preferably for technical issues and feature requests, open an issue on our GitHub repository. Your feedback is invaluable in helping us enhance the platform.
Getting Started
This section guides you through the initial steps required to start using the ShadowSelf API, including enabling access, obtaining credentials, and authenticating your requests.
API Key & Access
Before you can make any calls to the API, you need to configure access within your ShadowSelf account settings. Navigate to the Settings page. There you will find two crucial options related to API usage:
- API Access: This is a simple boolean toggle (on/off switch). By default, API access is disabled for all accounts as a
security precaution. You must explicitly enable this toggle to allow any API interactions with your account using the
Authorization
header. - API Key: This is your unique secret credential used for authenticating API requests via the recommended method. It's a 32-character alphanumeric string. You can generate a new API key directly on the settings page. Please note that only one API key can be active at a time per account. Generating a new key will invalidate the previous one. Treat your API key like a password – keep it secret and secure. Do not embed it directly in client-side code or commit it to public repositories.
Authentication
Every request to the ShadowSelf API must be authenticated to identify your account. We offer two methods for authenticating your requests:
Cookie
token
: You can authenticate by sending a cookie namedtoken
with the exact value of the session token used by your browser when logged into the ShadowSelf dashboard. You can typically find this using your browser's developer tools (Inspect Mode -> Application/Storage -> Cookies). While this method works, it is not recommended for programmatic access. The cookie value can change frequently (e.g., if you log out and back in, revoke all sessions, or change account details like your email address). Relying on this method can lead to fragile integrations that break unexpectedly. Use this primarily for quick testing or debugging if needed.Authorization Header (Recommended): This is the preferred and most reliable method for authenticating API requests. It uses your unique API key. First, ensure you have enabled API Access and generated an API Key in your settings. Then, for each API request you make, include an
Authorization
header in the HTTP request with the value formatted asBearer $API_KEY
. It's best practice to store your API key securely, for example, as an environment variable in your application or script, rather than hardcoding it.Example header:
Authorization: Bearer 4bacf7ed2.....
Test Integration
Once you have enabled API access and generated your API key, you should test your setup to ensure authentication is working
correctly. The easiest way is to make a simple GET
request to our dedicated test endpoint using the recommended Authorization header method.
You can use a tool like cURL
in your terminal. Replace $API_KEY
with your actual key:
curl -X GET "https://shadowself.io/api/test" \
-H "Accept: application/json" \
-H "Authorization: Bearer $API_KEY"
If your API key is valid and API access is enabled for your account, you should receive a 200 OK
HTTP status code and the
following text:
Response Text: Authentication is working ;)
If you don't receive the success message, double-check the following:
- Is the "API Access" toggle enabled in your ShadowSelf settings?
- Did you copy the entire 32-character API key correctly?
- Is the
Authorization
header formatted exactly asBearer $API_KEY
(with a space after "Bearer")? - Are you sending the request to the correct URL (
https://shadowself.io/api/test
)? - Ensure there are no leading/trailing spaces or special characters accidentally included in your key or header.
- If all else fails, check your network connection and regenerate your API key.
Once you receive the successful authentication message, you are ready to start making other calls to the ShadowSelf API!
Data Overview
This section details how to retrieve your identity data via the API. It covers the primary endpoint for listing all your synthetic identities associated with your account. You can use the unique id returned for each identity in this list to perform more specific actions in subsequent API calls.
List Identities:
Retrieves a list of all synthetic identities associated with the authenticated account. Each object in the returned array represents
one identity and contains summarized information. Use each one's id
to make other API calls related to this identity.
Request
This endpoint does not require any request body or query parameters.
Response Body
Returns No identities were found
If no identities are found for the account, it may return an error if you have not bad credentials
or improperly configured your account.
id
(string): A unique identifier for the synthetic identity. Use this ID for other API calls related to this specific identity.picture
(string): A base64 encoded string representing the identity's profile picture, resized to a low (256x256) dimension. you will need to add a data URI scheme likedata:image/png;base64,...
at the beginning to display the image.name
(string): The full name associated with the synthetic identity.email
(string): The email address associated with this identity including both the username and domain.phone
(string): The phone number associated with this identity in the E164 standard formatcard
(integer): The virtual payment card number associated with this identity,country
(string): The ISO 3166 country code derived from the identity's location.location
(string): The formatted location string associated with the identity, the city first then the country.accounts
(integer): The number of associated online accounts stored for this identity.
GET/
curl -X GET "https://shadowself.io/api/" \
-H "Accept: application/json" \
-H "Authorization: Bearer $API_KEY"
Response
[
{
"id": "iqe38349c0ab",
"picture": "VBORw0KGgoAAAANSUhEUgAAA...",
"name": "John Doe",
"email": "john.doe@shadowself.io",
"phone": "+157761348902",
"card": 4315343685134104,
"country": "CA",
"location": "Toronto, Canada",
"accounts": 21
},
{
"id": "awe9ff12a4de",
"picture": "U43Feql4+LpjAucJ5RRqgmW...",
"name": "Jane Doe",
"email": "jane@shadowself.io",
"phone": "+443639910827",
"card": 4156253336608285,
"country": "GB",
"location": "London, United Kingdom",
"accounts": 6
}
]
General Information
This section covers API endpoints for managing your identity's general information, including name, bio, and picture. You can retrieve and update these details using the appropriate endpoints.
Retrieve Information:
Retrieves detailed information for a specific synthetic identity identified by its unique ID. This endpoint provides a comprehensive view of the identity's attributes stored within ShadowSelf.
Request
This endpoint requires the identity's unique id
as a path parameter. It does not require any request body or query parameters.
Response Body
Returns a JSON object containing the detailed attributes of the requested identity. If the ID is not found or does not belong to the authenticated user, an appropriate error (e.g., 404 Not Found, 403 Forbidden) will be returned.
id
(string): The unique identifier for the synthetic identity.creation_date
(string): The timestamp (ISO 8601 format) indicating when the identity was created.proxy_server
(string): The proxy server address associated with this identity.user_agent
(string): The browser user agent string associated with this identity.picture
(string): A base64 encoded string representing the identity's profile picture. Prependdata:image/png;base64,
to display.name
(string): The full name associated with the synthetic identity.bio
(string): A short biography or description associated with the identity.age
(integer): The age associated with the identity.sex
(string): The assigned sex ('male' or 'female') for the identity.ethnicity
(string): The assigned ethnicity for the identity.location
(string): The formatted location string (e.g., "City, Country").email
(string): The primary email associated with this identity.phone
(string): The virtual phone number associated with this identity (E.164 format).card
(string): The virtual payment card number associated with this identity.
GET/identity/:id
curl -X GET "https://shadowself.io/api/identity/$IDENTITY_ID" \
-H "Accept: application/json" \
-H "Authorization: Bearer $API_KEY"
Response
{
"id": "ide38349c0ab",
"creation_date": "2023-10-27T10:30:00Z",
"proxy_server": "125.73.217.156",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
"picture": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8x...",
"name": "Jane Doe",
"bio": "Enjoys hiking and photography.",
"age": 32,
"sex": "female",
"ethnicity": "white",
"location": "Toronto, Canada",
"email": "jane.doe@shadowself.io",
"phone": "+14165550123",
"card": 4156253336608285
}
Regenerate Name:
Regenerates the full name for a specific synthetic identity. This uses a localization-aware generator based on the identity's country. You can optionally specify the desired sex to influence the generated name.
Request
This endpoint requires the identity's unique id
as a path parameter and accepts an optional JSON request body.
sex
(string, optional): Specify 'male' or 'female' to guide name generation. If omitted, the identity's current sex setting is used.
Response Body
Returns a JSON object containing the newly generated name.
name
(string): The newly generated full name for the identity.
PATCH/identity/regenerate-name/:id
curl -X PATCH "https://shadowself.io/api/identity/regenerate-name/$IDENTITY_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{"sex": "male"}'
Response
{
"name": "John Doe"
}
Regenerate Bio:
Regenerates the biography (bio) for a specific synthetic identity. This uses a localization-aware generator based on the identity's country to create a plausible short bio.
Request
This endpoint requires the identity's unique id
as a path parameter. It does not accept any request body or query parameters.
Response Body
Returns a JSON object containing the newly generated biography.
bio
(string): The newly generated biography for the identity.
PATCH/identity/regenerate-bio/:id
curl -X PATCH "https://shadowself.io/api/identity/regenerate-bio/$IDENTITY_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{}' # PATCH requires a body, even if empty
Response
{
"bio": "photographer, engineer, dreamer"
}
Regenerate Picture:
Regenerates the profile picture for a specific synthetic identity. This uses Stable Diffusion Core to generate a new picture influenced by the identity's characteristics. You can optionally provide specific characteristics in the request body to guide the generation process.
Request
This endpoint requires the identity's unique id
as a path parameter and accepts an optional JSON request body containing parameters to influence image generation.
sex
(string, optional): Must be 'male' or 'female'.age
(integer, optional): Must be a whole number between 18 and 60.ethnicity
(string, optional): Must be a valid ethnicity string from the allowed list (check dashboard for the list).bio
(string, optional): A string used as a prompt hint. Must be between 10 and 126 characters if provided.
Response Body
Returns a JSON object containing the newly generated profile picture as a base64 encoded string.
picture
(string): The new base64 encoded profile picture data. Prependdata:image/png;base64,
to display.
PATCH/identity/regenerate-picture/:id
curl -X PATCH "https://shadowself.io/api/identity/regenerate-picture/$IDENTITY_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{"age": 25, "ethnicity": "asian"}'
Response
{
"picture": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADtED8xABC..."
}
Update Information:
Updates one or more attributes of a specific synthetic identity. This endpoint allows modifying core characteristics like name, bio, age, sex, ethnicity, and profile picture.
Request
This endpoint requires the identity's unique id
as a path parameter and a JSON request body containing the fields to update.
name
(string, optional): Must be 2-30 characters long. Allows letters, spaces, hyphens, apostrophes.bio
(string, optional): Must be 10-126 characters long if provided (can be empty string""
to clear).sex
(string, optional): Must be 'male' or 'female'.age
(integer, optional): Must be a whole number between 18 and 60.ethnicity
(string, optional): Must be a valid ethnicity string from the allowed list.picture
(string, optional): Must be a valid base64 encoded string (without data URI prefix). Use with caution, typically regenerated rather than manually set.
Response Body
Returns a JSON object containing the current values of all the updatable fields (name, bio, sex, age, ethnicity, picture) after the update operation has been applied.
name
(string): The current name.bio
(string): The current biography.sex
(string): The current sex.age
(integer): The current age.ethnicity
(string): The current ethnicity.picture
(string): The current base64 encoded picture data.
PUT/identity/update/:id
curl -X PUT "https://shadowself.io/api/identity/update/$IDENTITY_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{"name": "Jane Doe", "age": 33}'
Response
{
"sex": "female",
"ethnicity": "white",
"age": 33,
"name": "Jane Doe",
"bio": "A software developer living in Toronto. Enjoys hiking and photography.",
"picture": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8x..."
}
Email Address
This section details the API endpoints for managing the email functionality associated with your synthetic identities. These endpoints allow you to interact with the identity's dedicated email account, enabling actions like retrieving emails, sending new messages, managing drafts, and deleting emails programmatically.
Retrieve Recent Emails:
Fetches a list of the most recent emails (up to 7 per mailbox) from the primary mailboxes (INBOX, Sent, Drafts, Junk) associated with the specified identity's email account. It also returns the total message count for each of these mailboxes. This provides an initial snapshot of recent activity and mailbox sizes.
Request
Requires the identity :id
as a path parameter. No request body or query parameters are needed.
Response Body
Returns a JSON payload containing message counts and separate arrays of recent email objects for each primary mailbox.
messagesCount
(integer): Total number of emails in the INBOX.sentMessagesCount
(integer): Total number of emails in the 'Sent' mailbox.draftsMessagesCount
(integer): Total number of emails in the 'Drafts' mailbox.junkMessagesCount
(integer): Total number of emails in the 'Junk' mailbox.inbox
(array): An array containing the most recent email objects from the INBOX.sent
(array): An array containing the most recent email objects from the 'Sent' mailbox.drafts
(array): An array containing the most recent email objects from the 'Drafts' mailbox.junk
(array): An array containing the most recent email objects from the 'Junk' mailbox.
Each email object within the arrays (`inbox`, `sent`, `drafts`, `junk`) includes:
uid
(integer): Unique ID of the email within its mailbox.messageID
(string): The globally unique Message-ID header value. Can be empty for drafts.from
(string): Sender's email address.to
(string): Primary recipient's email address.subject
(string): Email subject line.date
(string): Date and time (ISO 8601 format).body
(string): A snippet or the full body of the email.type
(string): Format of the body ('html' or 'text').inReplyTo
(string): The Message-ID this email is replying to.references
(array): An array of Message-IDs (string) for threading.attachments
(array): An array of attachment objects. Each object contains:filename
(string): Name of the attachment file.data
(string): Base64 encoded attachment data.
GET/email/:id
curl -X GET "https://shadowself.io/api/email/$IDENTITY_ID" \
-H "Accept: application/json" \
-H "Authorization: Bearer $API_KEY"
Response
{
"messagesCount": 125,
"sentMessagesCount": 58,
"draftsMessagesCount": 3,
"junkMessagesCount": 12,
"inbox": [
{
"uid": 125,
"messageID": "<b4a7e1f0-1234-5678-abcd-ef1234567890@example.com>",
"from": "sender@example.com",
"to": "jane.doe@shadowself.io",
"subject": "Project Update",
"date": "2023-10-27T14:30:00Z",
"body": "Here is the latest update...",
"type": "text",
"inReplyTo": null,
"references": [],
"attachments": [
{
"filename": "report.pdf",
"data": "JVBERi0xLjcK..."
}
]
}
],
"sent": [
{
"uid": 58,
"messageID": "<a1b2c3d4-e5f6-7890-1234-567890abcdef@shadowself.io>",
"from": "jane.doe@shadowself.io",
"to": "recipient@example.org",
"subject": "Re: Meeting Request",
"date": "2023-10-26T09:15:00Z",
"body": "Yes, that time works...",
"type": "text",
"inReplyTo": "<f0e9d8c7-b6a5-4321-fedc-ba0987654321@example.org>",
"references": [
"<f0e9d8c7-b6a5-4321-fedc-ba0987654321@example.org>"
],
"attachments": []
}
],
"drafts": [],
"junk": []
}
Retrieve More Emails:
Fetches the next batch of emails (up to 7) from a specific mailbox, used for pagination. Requires specifying the mailbox and the UID (`since`) of the oldest email currently loaded for that mailbox. The API returns emails with UIDs lower than the provided `since` value.
Request
Requires the identity :id
as a path parameter and query parameters to specify the mailbox and pagination reference point.
mailbox
(Query Parameter, string): The name of the mailbox to fetch from (e.g., "INBOX", "Sent", "Drafts", "Junk").since
(Query Parameter, integer): The UID of the oldest email currently fetched/displayed for this mailbox. The API will fetch the next batch of emails older than (i.e., with UIDs less than) this value.
Response Body
Returns a JSON payload containing the mailbox queried, the 'since' UID used, and an array of the next batch of emails found (up to 7).
mailbox
(string): The mailbox that was queried.since
(integer): The UID used as the reference point for fetching.nextEmails
(array): An array containing the next batch of email objects fetched. The structure of each email object is the same as described in "Retrieve Recent Emails". Returns an empty array if no older emails are found.
GET/email/load-more/:id
MAILBOX="INBOX"
SINCE_UID=104
curl -X GET "https://shadowself.io/api/email/load-more/$IDENTITY_ID?mailbox=$MAILBOX&since=$SINCE_UID" \
-H "Accept: application/json" \
-H "Authorization: Bearer $API_KEY"
Response
{
"mailbox": "INBOX",
"since": 104,
"nextEmails": [
{
"uid": 103,
"messageID": "<d2c1b0a9-f8e7-d6c5-b4a3-210987fedcba@domain.com>",
"from": "another.sender@domain.com",
"to": "jane.doe@shadowself.io",
"subject": "Follow Up",
"date": "2023-10-25T17:05:00Z",
"body": "Just checking in...",
"type": "text",
"inReplyTo": null,
"references": [],
"attachments": []
}
]
}
Retrieve Reply:
Fetches the full content of a specific email, identified by its unique message ID (`uuid` parameter, corresponding to the email's `messageID` header). This retrieves details needed for replying/forwarding like headers, subject, recipients, and attachments.
Request
Requires the identity :id
as a path parameter and the email's `uuid` (Message-ID) as a query parameter.
uuid
(Query Parameter, string): The unique Message-ID of the email to fetch.
Response Body
Returns a JSON payload containing the `uuid` queried and the full details of the fetched email.
uuid
(string): The message ID requested.fetchEmail
(object): An object containing the full email details, or null if not found. Includes:uid
(integer)messageID
(string)from
(string)to
(string)subject
(string)date
(string)body
(string)type
(string)inReplyTo
(string)references
(array of string)attachments
(array): Array of objects withfilename
(string) anddata
(string - base64).
GET/email/fetch-reply/:id
EMAIL_UUID_ENCODED="%3Ca1b2c3d4-e5f6-7890-1234-567890abcdef%40shadowself.io%3E"
curl -X GET "https://shadowself.io/api/email/fetch-reply/$IDENTITY_ID?uuid=$EMAIL_UUID_ENCODED" \
-H "Accept: application/json" \
-H "Authorization: Bearer $API_KEY"
Response
{
"uuid": "<a1b2c3d4-e5f6-7890-1234-567890abcdef@shadowself.io>",
"fetchEmail": {
"uid": 58,
"messageID": "<a1b2c3d4-e5f6-7890-1234-567890abcdef@shadowself.io>",
"from": "jane.doe@shadowself.io",
"to": "recipient@example.org",
"subject": "Re: Meeting Request",
"date": "2023-10-26T09:15:00Z",
"body": "<html><body>Yes, that time works for me. See you then...</body></html>",
"type": "html",
"inReplyTo": "<f0e9d8c7-b6a5-4321-fedc-ba0987654321@example.org>",
"references": [
"<f0e9d8c7-b6a5-4321-fedc-ba0987654321@example.org>"
],
"attachments": [
{
"filename": "calendar.ics",
"data": "QkVHSU46VkNBTEVOR..."
}
]
}
}
Send Email:
Sends a new email or a reply/forward from the identity's email account. Allows setting recipient, subject, body, attachments, and threading headers. Can optionally delete a draft if the sent email originates from one.
Request
Requires the identity :id
as a path parameter and a JSON payload with email details.
- Request Body (JSON):
to
(string): Primary recipient's email address.subject
(string): Subject line (max 126 chars).body
(string): Body content (min 2 chars).inReplyTo
(string, optional): Message-ID being replied to.references
(array, optional): Array of Message-IDs (string) for threading.attachments
(array, optional): Array of attachment objects (max 10). Each object:filename
(string): Filename.data
(string): Base64 content (max ~15MB).
draft
(integer, optional): UID of an existing draft to delete after sending.
Response Body
Returns a JSON payload confirming draft deletion and details of the sent email saved to 'Sent'.
draft
(integer): UID of deleted draft, or null.sentEmail
(object): Details of the sent email:uid
(integer): UID in 'Sent'.messageID
(string): New Message-ID assigned.from
(string): Sender's address.to
(string): Primary recipient.subject
(string): Subject line.date
(string): Date sent.body
(string): Body content.type
(string): Body type (html
ortext
)attachments
(array): Sent attachments.inReplyTo
(string): Message-ID being replied to.references
(array): Array of Message-IDs for threading.
POST/email/send-email/:id
curl -X POST "https://shadowself.io/api/email/send-email/$IDENTITY_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"to": "recipient@example.com",
"subject": "API Test Email",
"body": "This is the body of the test email sent via API.",
"inReplyTo": "<f0e9d8c7-b6a5-4321-fedc-ba0987654321@example.org>",
"references": ["<f0e9d8c7-b6a5-4321-fedc-ba0987654321@example.org>"],
"attachments": [
{
"filename": "document.pdf",
"data": "JVBERi0xLjcK..."
}
],
"draft": 123
}'
Response
{
"draft": 123,
"sentEmail": {
"uid": 59,
"messageID": "<e5d4c3b2-a1f0-e9d8-c7b6-a543210fedcb@shadowself.io>",
"from": "jane.doe@shadowself.io",
"to": "recipient@example.com",
"subject": "API Test Email",
"date": "2023-10-28T11:00:00Z",
"body": "This is the <b>HTML</b> body of the test email.",
"type": "html",
"attachments": [
{
"filename": "document.pdf",
"data": "JVBERi0xLjcK..."
}
],
"inReplyTo": "<f0e9d8c7-b6a5-4321-fedc-ba0987654321@example.org>",
"references": [
"<f0e9d8c7-b6a5-4321-fedc-ba0987654321@example.org>"
]
}
}
Forward Email:
Forwards an existing email (identified by UID) to a new recipient. Subject is prefixed "FWD: " and body prepended with headers. Original attachments are included.
Request
Requires identity :id
path parameter and JSON payload with UID and forward address.
- Request Body (JSON):
uid
(integer): UID of the email to forward (positive integer).forward
(string): Recipient email address for forwarding.
Response Body
Returns JSON payload with original UID, forward address, and details of the new forwarded email saved in 'Sent'.
uid
(integer): UID of the original forwarded email.forward
(string): Address email was forwarded to.forwardEmail
(object): Details of the new forwarded email (similar structure to `sentEmail`, includes attachments with data).
POST/email/forward-email/:id
curl -X POST "https://shadowself.io/api/email/forward-email/$IDENTITY_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"uid": 105,
"forward": "forward.recipient@another.com"
}'
Response
{
"uid": 105,
"forward": "forward.recipient@another.com",
"forwardEmail": {
"uid": 60,
"messageID": "<a0b1c2d3-e4f5-a0b1-c2d3-e4f5a0b1c2d3@shadowself.io>",
"from": "jane.doe@shadowself.io",
"to": "forward.recipient@another.com",
"subject": "FWD: Project Update",
"date": "2023-10-28T12:00:00Z",
"body": "\n<p><strong>--- Forwarded Message ---</strong></p>\n<p><strong>From:</strong> sender@example.com</p>\n...",
"type": "html",
"attachments": [
{
"filename": "report.pdf",
"data": "JVBERi0xLjcK..."
}
],
"inReplyTo": null,
"references": []
}
}
Save Draft:
Saves an email composition as a draft in 'Drafts'. Can replace an existing draft if its UID is provided (optional draft
field). Saves recipients, subject, body, attachments, and threading headers.
Request
Requires identity :id
path parameter and JSON payload with draft details. Uses PUT.
- Request Body (JSON): Structure matches "Send Email" body.
draft
(integer, optional): UID of existing draft to replace. Omit to create new.to
(string): Draft recipient.subject
(string): Draft subject.body
(string): Draft body.inReplyTo
(string, optional): Draft In-Reply-To header (Message-ID format).references
(array, optional): Draft References header (array of Message-IDs).attachments
(array, optional): Draft attachments (array of objects withfilename
anddata
).
Response Body
Returns JSON payload confirming old draft replacement and details of the saved draft in 'Drafts'.
draft
(integer): UID of replaced draft, or null.savedDraft
(object): Details of the saved draft (includes `uid`, `messageID` (null), `mailbox` ("Drafts"), `from`, `to`, `subject`, `body`, `type`, `date`, `attachments`, `inReplyTo`, `references`).
PUT/email/save-draft/:id
curl -X PUT "https://shadowself.io/api/email/save-draft/$IDENTITY_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"to": "recipient@example.com",
"subject": "Draft Subject",
"body": "Starting to write this email...",
"attachments": [ {"filename": "idea.txt", "data": "VGhpcyBpcyBteSB..."} ],
"draft": 45
}'
Response
{
"draft": 45,
"savedDraft": {
"uid": 48,
"messageID": null,
"mailbox": "Drafts",
"from": "jane.doe@shadowself.io",
"to": "recipient@example.com",
"subject": "Updated Draft Subject",
"body": "Continuing to write this email...",
"type": "text",
"date": "2023-10-28T13:00:00Z",
"attachments": [
{
"filename": "idea.txt",
"data": "VGhpcyBpcyBteSB..."
}
],
"inReplyTo": "<f0e9d8c7-b6a5-4321-fedc-ba0987654321@example.org>",
"references": [
"<f0e9d8c7-b6a5-4321-fedc-ba0987654321@example.org>"
]
}
}
Delete Email:
Moves a specific email (identified by mailbox and UID) to the 'Junk' folder. Emails moved to 'Junk' are automatically and permanently deleted after 7 days. This action cannot be performed on emails already residing in the 'Junk' folder.
Request
Requires identity :id
path parameter and JSON payload specifying mailbox and UID to move to Junk.
- Request Body (JSON):
mailbox
(string): Mailbox where the email currently resides (e.g., "INBOX", "Sent", "Drafts"). Cannot be "Junk".uid
(integer): UID of the email within the specified mailbox (positive integer).
Response Body
Returns JSON payload confirming mailbox and UID targeted for moving to Junk. Check HTTP status code (e.g., 200 OK) for success.
mailbox
(string): Mailbox specified in request.uid
(integer): UID specified in request.
DELETE/email/delete-email/:id
curl -X DELETE "https://shadowself.io/api/email/delete-email/$IDENTITY_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"mailbox": "INBOX",
"uid": 105
}'
Response
{
"mailbox": "INBOX",
"uid": 105
}
Phone Number
This section covers API endpoints for interacting with the virtual phone number associated with your synthetic identities, specifically for sending and receiving SMS messages. You can retrieve message history, fetch full conversations, send new messages, and manage conversations programmatically.
Retrieve Messages:
Retrieves a list of conversations associated with the identity's phone number. For each conversation (grouped by the other party's phone number), all messages are returned. The list is sorted with the most recent conversation first.
Request
Requires the identity :id
as a path parameter. No request body or query parameters are needed.
Response Body
Returns a JSON payload containing an array of message objects, where each object represents the latest message in a distinct conversation thread.
messages
(array): An array of the latest message objects from each conversation, sorted reverse-chronologically by message date. Each message object includes:messageID
(string): The unique identifier for the message.status
(string): Delivery status of the message (e.g., 'sent', 'delivered', 'failed', 'received').date
(string): Date and time the message was sent or created (ISO 8601 format).error
(string): Contains error code and message if the message failed (e.g., "30008: Unknown error"), otherwise an empty string.body
(string): The content of the SMS message.from
(string): Sender's phone number (E.164 format).to
(string): Recipient's phone number (E.164 format).
GET/phone/:id
curl -X GET "https://shadowself.io/api/phone/$IDENTITY_ID" \
-H "Accept: application/json" \
-H "Authorization: Bearer $API_KEY"
Response
{
"messages": [
{
"messageID": "SMxxxc4e6e6f7g8h9i0j1k2l3m4n5o6p",
"status": "received",
"date": "2023-10-28T10:30:05Z",
"error": "",
"body": "Okay, sounds good!",
"from": "+14155550000",
"to": "+14155551234"
},
{
"messageID": "SMaaab8d9e0f1g2h3i4j5k6l7m8n9o0",
"status": "delivered",
"date": "2023-10-28T09:15:00Z",
"error": "",
"body": "Can you call me later?",
"from": "+14155551234",
"to": "+14155559999"
}
]
}
Retrieve Conversation:
Fetches the complete message history for a specific conversation between the identity's phone number and another phone number (`addressee`). The messages are sorted reverse-chronologically (most recent first).
Request
Requires the identity :id
as a path parameter and the other party's phone number (`addressee`) as a query parameter.
addressee
(Query Parameter, string): The E.164 formatted phone number of the other party in the conversation (e.g., `+14155550000`). Cannot be the identity's own phone number.
Response Body
Returns a JSON payload containing the addressee number and an array of all message objects in the conversation.
addressee
(string): The phone number of the other party in the conversation.conversation
(array): An array containing all message objects exchanged between the identity and the addressee, sorted reverse-chronologically. The structure of each message object is the same as described in "Retrieve Messages", this means:messageID
(string): The unique identifier for the message.status
(string): Delivery status of the message (e.g., 'sent', 'delivered', 'failed', 'received').date
(string): Date and time the message was sent or created (ISO 8601 format).error
(string): Contains error code and message if the message failed (e.g., "30008: Unknown error"), otherwise an empty string.body
(string): The content of the SMS message.from
(string): Sender's phone number (E.164 format).to
(string): Recipient's phone number (E.164 format).
GET/phone/retrieve-conversation/:id
ADDRESSEE_PHONE="+14155550000"
ADDRESSEE_PHONE_ENCODED=$(echo "$ADDRESSEE_PHONE" | sed 's/+/%2B/')
curl -X GET "https://shadowself.io/api/phone/fetch-conversation/$IDENTITY_ID?addressee=$ADDRESSEE_PHONE_ENCODED" \
-H "Accept: application/json" \
-H "Authorization: Bearer $API_KEY"
Response
{
"addressee": "+14155550000",
"conversation": [
{
"messageID": "SMxxxc4e6e6f7g8h9i0j1k2l3m4n5o6p",
"status": "received",
"date": "2023-10-28T10:30:05Z",
"error": "",
"body": "Okay, sounds good!",
"from": "+14155550000",
"to": "+14155551234"
},
{
"messageID": "SMvvvw5d7d8e9f0g1h2i3j4k5l6m7n8",
"status": "delivered",
"date": "2023-10-28T10:29:50Z",
"error": "",
"body": "Great, thanks!",
"from": "+14155551234",
"to": "+14155550000"
},
{
"messageID": "SMyyyz3b1a2c3d4e5f6g7h8i9j0k1l2",
"status": "received",
"date": "2023-10-28T10:28:00Z",
"error": "",
"body": "Confirming receipt?",
"from": "+14155550000",
"to": "+14155551234"
}
]
}
Send Message:
Sends an SMS message from the identity's phone number to a specified recipient (`addressee`).
Request
Requires the identity :id
as a path parameter and a JSON payload containing the recipient and message body.
- Request Body (JSON):
addressee
(string): The recipient's phone number in E.164 format (e.g., `+14155550000`). Cannot be the identity's own number.body
(string): The text content of the SMS message. Must be between 2 and 160 characters.
Response Body
Returns a JSON payload containing the recipient addressee and details of the message successfully sent.
addressee
(string): The recipient phone number specified in the request.messageSent
(object): An object containing details of the sent message including:messageID
(string): The unique identifier for the message.status
(string): Delivery status of the message (e.g., 'sent', 'delivered', 'failed', 'received').date
(string): Date and time the message was sent or created (ISO 8601 format).error
(string): Contains error code and message if the message failed (e.g., "30008: Unknown error"), otherwise an empty string.body
(string): The content of the SMS message.from
(string): Sender's phone number (E.164 format).to
(string): Recipient's phone number (E.164 format).
POST/phone/send-message/:id
curl -X POST "https://shadowself.io/api/phone/send-message/$IDENTITY_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"addressee": "+14155550000",
"body": "Hello from the API!"
}'
Response
{
"addressee": "+14155550000",
"messageSent": {
"messageID": "SMzzzy9a8b7c6d5e4f3g2h1i0j9k8l7",
"status": "queued",
"date": "2023-10-28T14:00:00Z",
"error": "",
"body": "Hello from the API!",
"from": "+14155551234",
"to": "+14155550000"
}
}
Delete Conversation:
Permanently deletes all SMS messages exchanged between the identity's phone number and the specified `addressee` number. This action is irreversible.
Request
Requires identity :id
path parameter and JSON payload specifying the addressee whose conversation should be deleted.
- Request Body (JSON):
addressee
(string): The E.164 formatted phone number of the other party whose conversation history should be deleted.
Response Body
Returns JSON payload confirming the addressee whose conversation was targeted for deletion. Check HTTP status code (e.g., 200 OK) for success confirmation.
addressee
(string): The phone number specified in the request.
DELETE/phone/delete-conversation/:id
curl -X DELETE "https://shadowself.io/api/phone/delete-conversation/$IDENTITY_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"addressee": "+14155550000"
}'
Response
{
"addressee": "+14155550000"
}
Virtual Card
Under Development
The Virtual Card API is currently under development and is not yet available for use. We are actively working on expanding it to include more features and functionality.
Online Accounts
This section details the API endpoints for managing stored online account credentials associated with your synthetic identities. You can securely store website login information (username, password, website URL) and Time-based One-Time Password (TOTP) secrets for accounts you've signed up for using the identity's email or phone number, name etc...
Retrieve Accounts:
Retrieves all stored online account entries associated with the specified synthetic identity.
Request
Requires the identity :id
as a path parameter. No request body or query parameters are needed.
Response Body
Returns a JSON payload containing an array of stored account objects. The password
and totp
fields will contain
the client-side encrypted data as stored.
accounts
(array): An array of account objects associated with the identity. Each object includes:id
(integer): The unique identifier for this specific account entry.username
(string): The stored username for the online account.password
(string): The client-side encrypted password. Your client must decrypt this.website
(string): The URL of the website associated with the account.totp
(string): The client-side encrypted TOTP secret key. Your client must decrypt this to generate codes.algorithm
(string): The algorithm used for TOTP generation ('SHA1', 'SHA256', 'SHA512'), relevant only iftotp
is set.
GET/account/:id
curl -X GET "https://shadowself.io/api/account/$IDENTITY_ID" \
-H "Accept: application/json" \
-H "Authorization: Bearer $API_KEY"
Response
{
"accounts": [
{
"id": 101,
"username": "service_user_jd",
"password": "U2FsdGVkX1+v3Qw8aK9ZgslkdjfgPQ5/7a8s9d0fGHJKl==",
"website": "https://service.example.com",
"totp": "U2FsdGVkX1+abcDefGhiJKLmnoPqrStuVwxYz012345=",
"algorithm": "SHA1"
},
{
"id": 102,
"username": "tester_05",
"password": "U2FsdGVkX1+qwertyUIOPasdfghJKLzxcvBNM098765=",
"website": "https://anothersite.net",
"totp": null,
"algorithm": null
}
]
}
Add Account:
Adds a new online account entry associated with the specified identity. Remember to encrypt the password
and totp
secret on the client-side before sending.
Request
Requires the identity :id
as a path parameter and a JSON payload containing the account details.
- Request Body (JSON):
username
(string): The username (max 25 chars).password
(string): The client-side encrypted password data (e.g., Base64).website
(string, optional): The website URL.totp
(string, optional): The client-side encrypted TOTP secret key data (e.g., Base64).algorithm
(string, optional): The TOTP algorithm ('SHA1', 'SHA256', 'SHA512'). Required iftotp
is provided.
Response Body
Returns a JSON payload confirming the details of the added account, including its new id
. Sensitive fields are returned
as sent (encrypted).
id
(integer): The unique ID assigned.username
(string)password
(string): The encrypted password provided.website
(string)totp
(string): The encrypted TOTP secret provided.algorithm
(string)
POST/account/add-account/:id
ENCRYPTED_PASS="U2FsdGVkX19abcDefGhiJKLmnoPqrStuVwxYz012345="
ENCRYPTED_TOTP="U2FsdGVkX1+zxcvBNMqwertyUIOPasdfghJKL098765="
curl -X POST "https://shadowself.io/api/account/add-account/$IDENTITY_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"username": "forum_reader_12",
"password": "'"$ENCRYPTED_PASS"'",
"website": "https://communityforum.org",
"totp": "'"$ENCRYPTED_TOTP"'",
"algorithm": "SHA256"
}'
Response
{
"id": 103,
"username": "forum_reader_12",
"password": "U2FsdGVkX19abcDefGhiJKLmnoPqrStuVwxYz012345=",
"website": "https://communityforum.org",
"totp": "U2FsdGVkX1+zxcvBNMqwertyUIOPasdfghJKL098765=",
"algorithm": "SHA256"
}
Edit Account:
Updates an existing online account entry identified by its unique id
. Provide the account entry's id
in the
request body. Encrypt password
and totp
client-side if updating them.
Request
Requires the identity :id
(owner) path parameter and JSON payload with account entry ID and fields to update.
- Request Body (JSON):
id
(integer): The unique ID of the account entry to edit.username
(string): Updated username (max 25 chars).password
(string): Updated client-side encrypted password data.website
(string, optional): Updated website URL.totp
(string, optional): Updated client-side encrypted TOTP secret data.algorithm
(string, optional): The TOTP algorithm ('SHA1', 'SHA256', 'SHA512'). Required iftotp
is updated.
Response Body
Returns JSON payload confirming the details of the updated account entry. Sensitive fields returned encrypted.
id
(integer): ID of edited entry.username
(string)password
(string): Updated encrypted password.website
(string)totp
(string): Updated encrypted TOTP secret.algorithm
(string)
PUT/account/edit-account/:id
ACCOUNT_ENTRY_ID=101
NEW_ENCRYPTED_PASS="U2FsdGVkX1+UpdatedPassDataLooksLikeThisMaybe=="
curl -X PUT "https://shadowself.io/api/account/edit-account/$IDENTITY_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"id": '$ACCOUNT_ENTRY_ID',
"username": "jd_service_user_revised",
"password": "'"$NEW_ENCRYPTED_PASS"'",
"website": "https://service-updated.example.com"
}'
Response
{
"id": 101,
"username": "jd_service_user_revised",
"password": "U2FsdGVkX1+UpdatedPassDataLooksLikeThisMaybe==",
"website": "https://service-updated.example.com",
"totp": "U2FsdGVkX1+abcDefGhiJKLmnoPqrStuVwxYz012345=",
"algorithm": "SHA1"
}
Update Encryption:
Updates the encrypted password
and/or totp
fields for multiple account entries at once. This is primarily for
re-encrypting credentials client-side, e.g., after changing a master password.
Retrieve all accounts, re-encrypt sensitive fields (password, totp) client-side with the new key/method, then send an array
containing objects for each account entry needing update, including its id
and the newly encrypted password
and/or totp
.
Request
Requires identity :id
path parameter and JSON payload with an array of accounts with newly re-encrypted data.
- Request Body (JSON):
accounts
(array): Array of account objects to update. Each object:id
(integer): Unique ID of the account entry.password
(string): Newly client-side re-encrypted password data.totp
(string, optional): Newly client-side re-encrypted TOTP secret. Include only if the entry has a TOTP secret.
Response Body
Returns JSON payload confirming the update by echoing back the array of account objects sent. Check HTTP status code for success.
accounts
(array): Array of account update objects sent in the request.
PUT/account/update-encryption/:id
RE_ENCRYPTED_PASS_1="U2FsdGVkX1+NewKeyEncPassDataOne=="
RE_ENCRYPTED_TOTP_1="U2FsdGVkX1+NewKeyEncTotpDataOne=="
RE_ENCRYPTED_PASS_2="U2FsdGVkX1+NewKeyEncPassDataTwo=="
curl -X PUT "https://shadowself.io/api/account/update-encryption/$IDENTITY_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"accounts": [
{
"id": 101,
"password": "'"$RE_ENCRYPTED_PASS_1"'",
"totp": "'"$RE_ENCRYPTED_TOTP_1"'"
},
{
"id": 102,
"password": "'"$RE_ENCRYPTED_PASS_2"'"
}
]
}'
Response
{
"accounts": [
{
"id": 101,
"password": "U2FsdGVkX1+NewKeyEncPassDataOne==",
"totp": "U2FsdGVkX1+NewKeyEncTotpDataOne=="
},
{
"id": 102,
"password": "U2FsdGVkX1+NewKeyEncPassDataTwo=="
}
]
}
Delete Account:
Permanently deletes a specific stored online account entry using its unique ID. This action is irreversible.
Request
Requires the identity :id
(owner) path parameter and JSON payload specifying the unique ID of the account entry to delete.
- Request Body (JSON):
id
(integer): The unique ID of the account entry to delete (positive integer).
Response Body
Returns JSON payload confirming the ID of the account entry targeted for deletion. Check HTTP status code (e.g., 200 OK) for success.
id
(integer): The ID specified in the request.
DELETE/account/delete-account/:id
ACCOUNT_ENTRY_ID=103
curl -X DELETE "https://shadowself.io/api/account/delete-account/$IDENTITY_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"id": '$ACCOUNT_ENTRY_ID'
}'
Response
{
"id": 103
}
Websocket
The ShadowSelf WebSocket API leverages the WebSocket protocol to establish a persistent, two-way communication channel between your client application and our server. Unlike traditional HTTP polling, this allows the server to instantly push notifications about real-time events related to your synthetic identities, such as the arrival of new emails or SMS messages, directly to your application.
We chose WebSockets over alternatives like webhooks primarily for developer convenience and accessibility. Implementing a WebSocket client is straightforward in most environments, including browsers and server-side scripts, and crucially, it does not require your application to have a publicly accessible IP address or domain name.
To connect, establish a secure WebSocket connection to the bottom endpoint, replacing :id with the specific identity's unique ID.
Authentication happens during the initial connection handshake using the standard Authorization: Bearer YOUR_API_KEY
header, identical to the REST API authentication. Once connected (open event), the server
begins monitoring; disconnecting (close event) stops the monitoring process for that session.
WebSocket Endpoint: wss://shadowself.io/ws-api/:id
To maintain the connection through potential network intermediaries and verify its health, your client must implement a keep-alive mechanism. Periodically send a ping message to the server, which will respond with pong if the connection is active. Failure to receive a timely pong likely indicates a dropped connection.
All event notifications from the server are delivered as JSON-formatted text messages. Each message object includes a type field that identifies the event, along with a corresponding data payload. Your application should parse these messages and route them based on their type. Note that sending messages other than "ping" from your client to the server is not part of the intended use and will be ignored.
These message types and the data they care as follows:
Email Type
type
(string): The value is always "email".email
(object): An object containing details of the newly received email:uid
(integer): Unique ID of the email within its mailbox.messageID
(string): The globally unique Message-ID header value. Can be empty for drafts.from
(string): Sender's email address.to
(string): Primary recipient's email address.subject
(string): Email subject line.date
(string): Date and time (ISO 8601 format).body
(string): A snippet or the full body of the email.type
(string): Format of the body ('html' or 'text').inReplyTo
(string): The Message-ID this email is replying to.references
(array): An array of Message-IDs (string) for threading.attachments
(array): An array of attachment objects. Each object contains:filename
(string): Name of the attachment file.data
(string): Base64 encoded attachment data.
Message Type
type
(string): The value is always "message".message
(object): An object representing the newly received SMS message:messageID
(string): Unique identifier (e.g., Twilio SID).status
(string): Status (e.g., 'received').date
(string): Timestamp (ISO 8601).error
(string): Error details if applicable, else empty.body
(string): SMS content.from
(string): Sender's phone number.to
(string): Recipient's phone number (identity's number).
Websocket
wscat -H "Authorization: Bearer $API_KEY" -c wss://shadowself.io/ws-api/$IDENTITY_ID
# Manually type 'ping' and press Enter periodically