Skip to main content

Overview

github.com/tkhq/go-sdk/v2 lets you build server-side functionality for applications that interact with the Turnkey API. It exposes a client that constructs requests to the Turnkey API and authenticates, or stamps, them with a valid API key. This is normally the API key of your root organization.

Installation

Run go get from inside a Go module:

Initializing

Build a stamper from your API private key, then pass it to NewClient along with your organization ID.
The import is aliased to turnkey because the module path ends in /v2. Without the alias, some tooling assumes the package name is v2.

Parameters

turnkey.NewAPIKeyStamper parameters

string
required
The API Private Key used to sign requests. This is normally the API Private Key for your root organization.
...APIKeyStamperOption
Optional configuration for the stamper. Use turnkey.WithSignatureScheme to set the signature scheme. The default is tkcrypto.SchemeP256.

turnkey.NewClient parameters

Stamper
required
The request stamper that signs API requests. Create one with turnkey.NewAPIKeyStamper(apiPrivateKey). The public key is derived from the private key, so there is no separate public-key parameter. You can also provide your own implementation of the Stamper interface for advanced signing setups.
string
required
The default organization ID for requests made by this client. Individual request structs can override it with their own OrganizationID field when targeting a sub-organization.
...OptionFunc
Optional variadic configuration functions. See Configuration options.

Configuration options

Pass any number of With* functions as trailing arguments to NewClient.

Making requests

Unlike some of our other SDKs, there is no separate apiClient() object. The client returned by NewClient is the API client. Every Turnkey endpoint is a method on it, and every method takes a context.Context and a typed request struct, returning a typed response and an error.
The OrganizationID field defaults to the client’s organization ID. Set it only when you need to target a sub-organization. For activity requests, TimestampMs is set automatically. Common methods include:

Context and cancellation

Because every method takes a context.Context, you get per-call timeouts and cancellation:

Activity polling

Methods that submit asynchronous activities poll to completion automatically. You receive the final result rather than a pending activity.
Tune polling with WithActivityPollInterval and WithActivityPollTimeout. If an activity reaches a failed or rejected terminal state, the SDK returns an ActivityFailedError. If an activity needs consensus approval, the SDK returns an ActivityRequiresApprovalError.

Signing without submitting

Some server flows need a request signed by your root organization’s key but submitted by another party, such as a browser client. For these flows, use the Stamp* variant of a method. Instead of sending the request to Turnkey, it returns a *SignedRequest that you can forward.
string
required
The Turnkey endpoint URL for the signed request.
string
required
The serialized JSON request body that was signed.
*Stamp
The authentication stamp. Add Stamp.HeaderName as the HTTP header name and Stamp.HeaderValue as the HTTP header value when submitting the request.
RequestType
The request type, such as query or activity.

Authentication flows

The SDK exposes methods for common authentication flows. These methods are regular client calls: pass a context.Context, pass the typed request struct, and handle the typed response.

Auth Proxy

If your deployment uses the Turnkey Auth Proxy, configure the proxy config ID once with WithAuthProxyConfigID, then use the corresponding AuthProxy* method for the auth step you want to run. The most common server-side use is OTP, because it lets your backend trigger email or SMS codes without exposing a root organization API key to the client.
These methods call Turnkey’s hosted Auth Proxy. They are not a proxy server that you host. Keep this section as a configuration pattern: OTP, OAuth, and email auth parameters mirror the direct flows documented below, so they are not repeated here.

OTP

OTP auth is a three-step flow: send a code, verify the code, then exchange the verification token for a session.
Required parameters:
string
required
Application name shown in the OTP message for InitOTP.
string
required
Email address or phone number to send the OTP code to.
string
required
OTP delivery channel, such as OTP_TYPE_EMAIL or OTP_TYPE_SMS.
string
required
Encrypted code bundle passed to VerifyOTP. It is encrypted using the target bundle from InitOTP and includes the OTP code and client-side public key.
string
required
OTP flow ID returned by InitOTP.
ClientSignature
required
Signature over the verification token ID and public key for OTPLogin.
string
required
Client-side public key to bind to the resulting session.
string
required
Signed token returned by VerifyOTP and consumed by OTPLogin.
Common optional fields include OrganizationID, ExpirationSeconds, InvalidateExisting, SessionProfileID, EmailCustomization, SmsCustomization, OTPLength, and UserIdentifier.

OAuth

Use OAuthLogin when you already have an OIDC token and want to create a Turnkey session bound to a client-side public key.
string
required
Base64-encoded OIDC token from an OAuth provider.
string
required
Client-side public key to bind to the resulting session.
Common optional fields include OrganizationID, ExpirationSeconds, InvalidateExisting, and SessionProfileID.

Email auth

Use EmailAuth to send an authentication credential bundle to a user’s email address. The bundle is encrypted to the target public key.
string
required
Email address of the authenticating user.
EmailAuthCustomizationParams
required
Email customization parameters. AppName is required by the email template.
string
required
Client-side public key that the email auth credential bundle will be encrypted to.
Common optional fields include OrganizationID, APIKeyName, ExpirationSeconds, InvalidateExisting, ReplyToEmailAddress, SendFromEmailAddress, and SendFromEmailSenderName.

Error handling

Every method returns (*Response, error). Check the error before using the response. API-level failures do not panic.
Typed errors include: Use turnkey.ActivityFromApprovalError(err) to recover the full activity from an ActivityRequiresApprovalError when you need to drive your own approval flow.

Signature schemes

NewAPIKeyStamper defaults to the P256 scheme. To use a different API key scheme, import the crypto module and pass WithSignatureScheme:
Supported schemes:

Custom stampers

Most integrations should use NewAPIKeyStamper. If you need signing to happen somewhere else, such as an HSM, KMS, remote signing service, or WebAuthn ceremony, implement the Stamper interface and pass that implementation to NewClient. Every request the client sends is authenticated, or stamped, before it leaves your process. The client delegates that step to any value implementing this interface:
Stamp receives the serialized request body and returns a *turnkey.Stamp, which carries the HTTP header the client attaches to the outbound request:

Implementing a custom stamper

A stamper only needs to sign the exact bytes it is handed and return the header the API expects. The skeleton below shows the shape every implementation shares: take the body, produce a signature with whatever mechanism you control, and package it as a Stamp.
After you have a signer value that implements the Signer interface, pass the custom stamper to NewClient in place of the API key stamper:
Sign the body bytes as received. Re-serializing the request can reorder fields or change whitespace, which invalidates the signature Turnkey verifies against.

Example: WebAuthn stamper

A WebAuthn stamper authorizes requests with a passkey or hardware authenticator instead of a static API key. The ceremony that produces the assertion runs wherever the authenticator lives, usually a browser or native client, so the stamper’s job is to derive the WebAuthn challenge from the request body, obtain an assertion, and encode it into the X-Stamp-WebAuthn header the API expects. The Go SDK does not currently expose a dedicated WebAuthn stamper constructor, so this example shows the interface you would implement around your own WebAuthn transport. The stamp payload uses the generated turnkey.WebAuthnStamp type.
Wire it into the client the same way as any other stamper:
The client now attaches a WebAuthn stamp to every request without any change to how you call Turnkey endpoints. The typed request and response models are identical to the API key path.