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
Rungo get from inside a Go module:
Initializing
Build a stamper from your API private key, then pass it toNewClient 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 ofWith* functions as trailing arguments to NewClient.
Making requests
Unlike some of our other SDKs, there is no separateapiClient() 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.
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 acontext.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.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 theStamp* 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 acontext.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 withWithAuthProxyConfigID, 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.OrganizationID, ExpirationSeconds, InvalidateExisting,
SessionProfileID, EmailCustomization, SmsCustomization, OTPLength, and
UserIdentifier.
OAuth
UseOAuthLogin 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.
OrganizationID, ExpirationSeconds, InvalidateExisting, and
SessionProfileID.
Email auth
UseEmailAuth 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.
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.
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:
Custom stampers
Most integrations should useNewAPIKeyStamper. 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 aStamp.
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 theX-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.