Blog

An in-depth guide to Turnkey's Wallets-as-a-service (WaaS) API

Developer
·
May 2, 2025

Embedded wallets are becoming popular among developers building crypto applications. Applications like Moonshot, Infinex, Magic Eden, and Legend are using WaaS solutions to build user-friendly experiences and remove the friction of onboarding with seed phrases and third-party wallets.

Developers can also benefit from using Wallet-as-a-service solutions, as they often provide software development kits and support different programming languages and frameworks. 

Turnkey, like most WaaS providers, offers an HTTP API and different SDKs for developers, so they can integrate embedded wallets and transaction automation. In this guide we’ll go over how Turnkey’s API works and explore each of the different concepts so you can start understanding and building your own applications using Turnkey.

Setting up your API keypair on Turnkey

To get started using Turnkey via the API, you’ll need an API keypair. When logged into the Turnkey dashboard click on your icon in the top-right hand corner, click user details, and on this page click “Create API Key” to generate your API key. 

The private key provided in this instance acts like a typical API key compared to other services. It controls what you, as a user, can do on Turnkey – so this is displayed once for safety and should be kept private (i.e. only used server-side, not exposed in GitHub repositories, etc.).

Each API key is tied to a specific user in your organization. When creating a new user in your organization, you can choose whether or not to provide access to Turnkey via the web, the API, or both. Developers can also generate API keys with the Turnkey CLI tool if preferred, too.

When creating your API key, you might have noticed that this action required an approval and gave you a summary of the activity

On Turnkey, every action taken on the platform constitutes an activity. You can think of these similar to CRUD actions on most traditional web applications. They could be creating a new user, reading a wallet’s balance, signing transactions, or any number of actions in your app. They are actions taken by a user, which typically changes or requests data from Turnkey.

Understanding Turnkey's core concepts

The main concepts which make up the bulk of Turnkey’s platform are Organizations, Sub-Organizations, Users, and Policies

Organizations are a top-level group of users, wallets, and associated policies. If you’re a project using Turnkey, this will likely represent your team, such as executive members, developers, etc.

Of the users in your team, some (or all) members will make up the Root Quorum. You can think of this like a group of users with “admin” privileges. They can perform any action, and any updates they want to make require a certain threshold of approvals from other root users.

Wallets themselves are associated with organizations (not individual users) and sub-organizations, and can contain any number of accounts. For more technical details on their implementation, you can take a look at Hierarchical Deterministic (HD) Wallets.

Policies determine what actions specific users can take. For example, certain members of your organization might be able to sign sensitive transactions, while others might only be allowed to approve transactions with a specific value or to-and-from specific accounts. These form the majority of the important primitives for organizations. 

What makes Turnkey especially flexible is the primitive of sub-organizations. These function exactly as you’d expect: they are nested organizations, but are not controlled by the parent organization. For this reason, sub-orgs are typically used to represent non-custodial accounts for end users.

Turnkey's primitives and our WaaS API

So, how do these concepts relate to the Turnkey API?

As you might expect, all of the examples mentioned constitute activities and can be executed via the API. Here’s a simple JavaScript example for getting an organization’s list of wallets.

const options = {
  method: 'POST',
  headers: {'X-Stamp': '<api-key>', 'Content-Type': 'application/json'},
  body: '{"organizationId":"<string>"}'
};

fetch('https://api.turnkey.com/public/v1/query/list_wallets', options)
  .then(response => response.json())
  .then(response => console.log(response))
  .catch(err => console.error(err));

All requests which only fetch information (i.e. don’t modify any resources) are prefixed with “query”, while requests which execute securely (i.e. update, create or delete something) are prefixed with “submit”. Before each submit action is successfully completed, it checks against the organization’s Policies. You can view the full HTTP API Reference for a full list of endpoints.

Let’s take a look at the structure of this specific API request in more detail.

The anatomy of a Turnkey request

You might have noticed that in our request we needed to send an “X-Stamp” header, which is a JSON object. Every request to Turnkey made by a client which includes a Stamp, and is therefore always a POST request. A stamp simply authorizes an action on Turnkey. 

Traditionally, you might be familiar with sending a POST request with your raw API key included in the header to perform an action on a platform. Instead, a stamp is a signature created from your request using your private API key or another form of authentication, e.g. biometrics. This is the way Turnkey authenticates actions on the platform. 

You can view how to create a stamp from scratch with your API key here, but for most developers it’s more than likely you will be using Turnkey’s provided tooling rather than generating stamps manually. It’s still good to know what is happening with each API request under the hood, though.

These SDKs work together to allow you to perform actions on Turnkey via your own organization, such as the creation of new end users/sub-organizations, and allow your end users to perform actions of their own such as signing or sending transactions.

Let’s go through an example, and explore how you can use these primitives to use the Turnkey API and related SDKs.

Web app architecture and Turnkey’s SDKs

Interacting with the Turnkey API is usually done in two main ways: by the parent organization directly, and by end-users (typically sub-organizations) calling the Turnkey API to perform an action on their account.

This distinction also fits well with how most web applications are built, with a general distinction between the frontend and the backend. Your backend/server code will control actions taken by your parent organization, while the frontend will handle the stamping and execution of user actions.

Think of a simple application flow like this:

  • A user signs up to your app with their email, with flow initiated by parent org on backend
  • A successful sign-up creates a sub-organization and returns the end user an API key
  • Any subsequent requests from the user, such as funding a wallet or making a transaction, is stamped by the user’s API key
  • The backend can kick off any other parent organization tasks, and serve any “read-only” data such as the user’s balance, wallet address, etc. 

This separation keeps the parent organization secure, by never exposing parent organization credentials to the end-user on the frontend. In the same way, the end user credentials are never exposed to the parent organization on the backend. The parent org simply provides them with a method to create their own credentials. 

This setup establishes the building blocks of a secure and non-custodial approach to building an application with Turnkey.

More on SDKs and stamping

At Turnkey, we provide multiple web-based SDKs which abstract away the generation of clients and stamping for you. The most relevant ones are likely to be @turnkey/sdk-browser, @turnkey/sdk-server, and @turnkey/sdk-react. These function like most web API SDKs, where developers will initialize an API Client and easily make calls to perform any activity on Turnkey.

We also provide stampers separately outside of these dedicated JS/TS SDKs, to handle signing requests. This makes it easier to use Turnkey with different clients, for example mobile applications, and Telegram mini-apps. We have a monorepo of all the packages here.

A closer look at the policy engine

Every request made to Turnkey is run through the policy engine for each organization to ensure the action requested is authorized. Policies can be bypassed by root users, but otherwise must be configured by the organization users at hand to set certain policies. 

For example, a parent organization may allowlist certain addresses which users can distribute funds to. Another example might be setting a policy inside each sub-organization to prevent users from sending funds to known malicious addresses (which can still be overridden by the end user if chosen to do so). 

This works with Turnkey’s API by passing in stamped requests through the policy engine, which determines whether an activity is valid or not. Valid activities return a “COMPLETED” status via the API, while activities that don’t pass the configured policies return a “FAILED” status. We offer specific policy methods for both Ethereum and Solana, and you can see a comprehensive list of examples here.

Benefits of using Turnkey’s wallets-as-a-service solutions

Using Turnkey’s API for wallet generation and management provides benefits for both developers and end-users. Some of them include:

  • Non-custodial architecture: The sub-organization model creates a true separation between your organization and end users, providing genuine non-custodial wallets
  • Policy engine flexibility: The robust policy framework allows for granular control over transactions while maintaining user autonomy
  • Security-first approach: The stamping system for API requests provides stronger security than traditional API key authentication, in combination with Turnkey’s TEE-based architecture
  • Separation of client-side and server-side actions: The handling of parent organization actions (server-side) and end-user actions (client-side) creates a secure way to develop crypto applications
  • Comprehensive SDKs:  We support various platforms through JS/TS SDKs, and provide further packages for other clients for straightforward integration
  • Organization hierarchy: The organization/sub-organization model creates a natural way to manage different user types and permission levels

Turnkey’s WaaS API is extremely flexible for developers, and in combination with organizations and policies, provides secure private key management infrastructure for developers to ideate, build, and scale their product.

If you’re working on a new crypto app, or want to automate transactions across your organization, you can start using our SDKs to simplify the developer experience – and build a product experience that your customers will thank you for. 

If you want to get started, check out our developer docs, join our developer community for support questions, or get in touch with our Sales team for more information.

Happy building!