Client SDKs

Note: language-specific SDKs can be found here.


You can obtain your API keys from the 'API Keys' screen (see organization settings).

There are two keys:

  • A secret key for server-side use.
  • A public key for client-side use. This key can only be used by also setting a referrer domain.


Do not expose the secret key in client-side code and don't commit it to your source code versioning repository.

Secret key usage

The secret key can be used in bearer token authentication:

  curl --request POST \
  --url \
  --header 'authorization: Bearer sk_...' \

Replace sk_... by your secret API key.

Public key usage

The public key can be used by passing it as a URL parameter:

Replace pk_... by your public API key.

Important — you must also set a so-called referrer domain from which you're going to make client-side calls to the Sprouted API. This domain can be entered in your organization's API Keys screen.


400 Bad Request is returned for invalid requests. In most cases the response contains an error description.


Call the customer API endpoint whenever a new user is created in your application.

The following attributes are supported:

  • customer -> id - your internal customer/user ID (optional)
  • customer -> email_address - the user's email address (required)
  • customer -> name -> full - the user's full name (required*)
  • customer -> name -> first - the user's first name (required*)
  • customer -> name -> last - the user's last name (required*)
  • customer -> encrypted_fields - comma-separated list of encrypted field names

Providing id is optional. If one is provided you can refer to the customer using this ID instead of the ID created by the Sprouted API. An ID can be a number or string and must be unique across the customers sent to Sprouted.

You must either provide full or provide first and/or last name but you can't leave all name fields empty.

Note: only the full attribute can be encrypted at this time.

Create customer
Example request:
  curl --request POST \
  --url \
  --header 'authorization: Bearer sk_...' \
  --header 'content-type: application/json' \
  --data '{
  "name": {
    "first": "Joe",
    "last": "Doe"
  "email_address": ""

A successful response returns 201 Created.

Example response:
  { "id": "{customer-id}" }

Update customer

Update an existing customer by passing its internal or external ID.

  curl --request PUT \
  --url{internal-or-external-customer-id} \
  --header 'authorization: Bearer sk_...' \
  --header 'content-type: application/json' \
  --data '{
  "email_address": ""

A successful response returns 200 OK.

Example response:
  { "id": "{customer-id}" }

Delete customer

Delete an existing customer by passing its internal or external ID.

Example request:
  curl --request DELETE \
  --url{internal-or-external-customer-id} \
  --header 'authorization: Bearer sk_...' \
  --header 'content-type: application/json'

A successful response returns 200 OK.

Example response:

Customer Event

Use the customer event API endpoint to record important customer events.

Examples of customer events:

  • Your user starts to use a key feature
  • The user upgrades or downgrades to another plan
  • The user closes her account

When you're using the inbound email feature of Sprouted then events are created for every new email sent by the user. Events created by you via the API and inbound message events are combined into a single timeline of events per customer.

The following attributes are supported:

  • type - event type i.e. its label or name
  • tuples - array of key-value pairs and data types
  • tuples -> data - key-value pair
  • tuples -> data_type - type of value (string, internal, Boolean)

Create customer event
Example request:
  curl --request POST \
  --url{internal-or-external-customer-id}/events \
  --header 'authorization: Bearer sk_...' \
  --header 'content-type: application/json' \
  --data '{
  "type": "plan-change",
  "tuples": [{
    "data": {
      "previous-plan": "free"
    "data_type": "string"
  }, {
    "data": {
      "new-plan": "pro"
    "data_type": "string"

A successful response returns 201 Created.

The contents of the type attribute will be converted to lower case and spaces converted to dashes.

The tuples attribute holds an array of key-value pairs and a data_type attribute which defines the value type. Supported data types are string, number, and Boolean. If you omit the data type then string is assumed. Pass true or false as Boolean values.

Example response:
  { "id": "{customer-event-id}" }


You can pass encrypted fields to Sprouted. At this time only the customer -> name -> full attribute can be encrypted. The secret-key cryptography of Sprouted is based on Libsodium.

Typical encryption flow:

  • Set the full attribute to the nonce and the encrypted full name, separated by a comma. See below for an example.
  • Set the encrypted_fields attribute to name.full.
  • Look at the newly added customer in Sprouted. The user's name is displayed as a string of hex codes i.e. gibberish.
  • Install the Sprouted browser extension.
  • Enter the encryption key in the options screen.
  • Reload the customer page. The name is now readable!

Encryption code example:

  require 'rbnacl'

key = RbNaCl::Random.random_bytes(RbNaCl::SecretBox.key_bytes)
secret_box =
nonce = RbNaCl::Random.random_bytes(secret_box.nonce_bytes)
encrypted_text = secret_box.encrypt(nonce, 'Joe Doe')

hex_key = RbNaCl::Util.bin2hex(key)
hex_nonce = RbNaCl::Util.bin2hex(nonce)
hex_encrypted_text = RbNaCl::Util.bin2hex(encrypted_text)

Enter the hex_key value in the options screen of the browser extension.

The hex_nonce and hex_encrypted_text values are used by the full attribute:

  curl --request POST \
  --url \
  --header 'authorization: Bearer sk_...' \
  --header 'content-type: application/json' \
  --data '{
  "customer": {
    "encrypted_fields": "name.full",
    "name": {
      "full": "{hex_nonce},{hex_encrypted_text}"

Notice that the nonce and encrypted string must be separated by a comma. Don't add any extra whitespace.

Ruby examples

Add the following line to your Gemfile and run bundle:

  gem 'sprouted_app', git: ''

You can also build and install the gem locally:

  git clone sprouted-gem

cd sprouted-gem

gem build sprouted_app.gemspec

gem install sprouted_app

Once the gem has been installed you can use it to create a customer:

  require 'sprouted_app'

SproutedApp.configure do |config|
  config.access_token = 'sk_live_...'

name = 'Joe', last: 'Doe')

customer = '--your customer id--',
  email_address: '', name: name){ customer: customer })

Next you can create customer events:

  tuple1 =
  { data: { old_plan: "Free" }, data_type: "string" })

tuple2 =
  { data: { new_plan: "Team Plan" }, data_type: "string" })

event = 'plan-upgrade', tuples: [tuple1, tuple2])

result ='--your customer id--', { event: event })

Rails usage

For Rails 4.2 and higher it is recommended to use ActiveJob to make out-of-band calls to Sprouted.

Step 1: add a file called sprouted.rb to config/initializers containing:

  SproutedApp.configure do |config|
  config.access_token = ENV.fetch('SPROUTED_API_KEY')

Step 2: add a file called sprouted_job.rb to app/jobs containing:

  class SproutedJob < ApplicationJob

  queue_as :default

  def perform(user:)
    name = user.first_name, last: user.last_name)
    customer =,
      email_address: user.email_address, name: name){ customer: customer })


Note: exception handling is omitted for the sake of brevity.

You can invoke the Sprouted customer job by calling:

  Sprouted::CustomerJob.perform_later(user: @user)

HTTP code examples

The examples below show how to perform http POSTs in several popular languages:

C# (with RestSharp)

  var client = new RestClient("");
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", "Bearer sk_...");
request.AddParameter("application/json", "{ name: { first: 'Joe', last: 'Doe' }, email_address: '' }", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);


  package main

import (

func main() {

	url := ""

	payload := strings.NewReader("{ name: { first: 'Joe', last: 'Doe' }, email_address: '' }")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("content-type", "application/json")
	req.Header.Add("authorization", "Bearer sk_...")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)



Java (with Unirest)

  HttpResponse response ="")
  .header("content-type", "application/json")
  .header("authorization", "Bearer sk_...")
  .body("{ name: { first: 'Joe', last: 'Doe' }, email_address: '' }")

JavaScript (with JQuery)

  var settings = {
  "async": true,
  "crossDomain": true,
  "url": "",
  "method": "POST",
  "headers": {
    "content-type": "application/json",
    "authorization": "Bearer sk_..."
  "data": "{ name: { first: 'Joe', last: 'Doe' }, email_address: '' }"

$.ajax(settings).done(function (response) {

Note: don't forget to set your referrer domain or else your request will be rejected.

Node.js (with Request)

  var request = require("request");

var options = {
  method: 'POST',
  url: '',
  headers: {'content-type': 'application/json', authorization: 'Bearer sk_...'},
  body: '{ name: { first: \'Joe\', last: \'Doe\' }, email_address: \'\' }'

request(options, function (error, response, body) {
  if (error) throw new Error(error);


Note: this should be executed server-side in order to safeguard your secret API key.

PHP (with HTTP v2)

  $client = new http\Client;
$request = new http\Client\Request;

$body = new http\Message\Body;
  name: {
    first: 'Joe',
    last: 'Doe'
  email_address: ''


  'content-type' => 'application/json',
  'authorization' => 'Bearer sk_...'

$response = $client->getResponse();

echo $response->getBody();

Python (with Requests)

  import requests

url = ""

payload = "{ name: { first: 'Joe', last: 'Doe' }, email_address: '' }"
headers = {
    'content-type': "application/json",
    'authorization': "Bearer sk_..."

response = requests.request("POST", url, data=payload, headers=headers)


Ruby (with Typhoeus)

  require 'typhoeus'
require 'json'

response ='',
  body: {
    name: {
      first: 'Joe',
      last: 'Doe'
    email_address: ''
  headers: {
    'authorization': 'Bearer sk_...',
    'content-type': 'application/json'

puts response.success?
puts response.body

Ruby (with Net::HTTP)

  require 'uri'
require 'net/http'
require 'openssl'

url = URI('')

http =, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request =
request['content-type'] = 'application/json'
request['authorization'] = 'Bearer sk_...'
request.body = "{ name: { first: 'Joe', last: 'Doe' }, email_address: '' }"

response = http.request(request)
puts response.read_body
© Releasewise B.V. 2020 · Terms of Service · Privacy Policy · Information Security · Feedback · API · Main Site