Kepla API

Search

Search offers advanced querying of records across the Kepla database.

Kepla's search functionality is powered by Elasticsearch. Through the API you have full access to make custom queries on record types using Elasticsearch's standard query language.

These endpoints power Kepla's internal lists feature, and due to how the data is indexed will include a full list of all a record's transactions, activity and relationships along with the standard record object.

The search APIs support our standard limits, order and pagination parameters.

Note: The API doesn't currently support using aggregations in Elasticsearch, and will throw an error if you try.

Search Overview

{
  "{fieldId}": "Example field value",
String
  activities: [
Array

A full list of all activities on the record. See the activities reference for full documentation

    {
    { ... }
Object

Blank JSON

    }
  ]
  "createdAt": "2016-05-30T15:46:23.633Z",
String (Date-time)
  "id": "25d78a92-5b36-4f49-98c7-472ba358b65c",
String
  "meta": {
  "meta": { ... }
Object
    "activities": [
    "foo",
    "foo",
    "foo"
  ],
Array
    "transactions": {
    "transactions": { ... }
Object
      "totalRevenue": 1523,
Integer
      "totalFees": 61,
Integer
      "totalShipping": 152,
Integer
      "totalTax": 137,
Integer
      "count": 3,
Integer
      "averageRevenue": 507.6666666666667,
Number
      "averagePeriodInDays": 56,
Integer
      "retentionInDays": 266,
Integer
      "totalTransactionPeriodInDays": 266,
Integer
      "totalBySource": {
      "totalBySource": { ... }
Object
      },
      "totalByCampaign": {
      "totalByCampaign": { ... }
Object
      },
      "totalByFund": {
      "totalByFund": { ... }
Object
      }
    }
  },
  "primaryKey": "[email protected]",
String

This is set based on the primary key field on a type. It will be updated if you ever update the database primary key, so only rely on it for deduping.

  relationships: [
Array
    {
    { ... }
Object

Blank JSON

    }
  ]
  tags: [
Array
    {
    { ... }
Object

List

      "items": {
      "items": { ... }
Object
        "color": "#f4983c",
String

(Optional) A HEX code for the color of the tag in the app.

        "id": "a99cfd2a-829c-483d-8c4f-2c8627c027a4",
String (Uuid)
        "name": "api tag",
String

Friendly name for the tag in the app and in exports

        "typeId": "a387d549-2ebd-47f8-a8e3-b54a1d1d6d04"
String (Uuid)
      }
    }
  ]
  teams: [
Array
    {
    { ... }
Object

List

      "items": {
      "items": { ... }
Object
        "accountId": "e1f4cca4-1cbc-42cb-bb2f-5bbbab513f5c",
String
        "createdAt": "2016-07-19T11:06:52.692Z",
String
        "id": "0dd4e0e0-635f-4f07-8edd-d41de58af810",
String
        "name": "Staff",
String
        users: [
Array

An array of users who are members of the team.

          {
          { ... }
Object

Condensed

            "createdAt": "2015-11-02T00:30:23.968Z",
String
            "email": "[email protected]",
String (Email)
            "id": "77c8a907-40b7-40ab-91ad-8034df0fa7a0",
String
            "name": "Tom Maitland"
String
          }
        ]
      }
    }
  ]
  transactions: [
Array
    {
    { ... }
Object

Blank JSON

    }
  ]
  "typeId": "a387d549-2ebd-47f8-a8e3-b54a1d1d6d04",
String
  "updatedAt": "2016-07-20T13:02:31.515Z",
String
  users: [
Array
    {
    { ... }
Object

List

      "items": {
      "items": { ... }
Object
        "createdAt": "2015-11-02T00:30:23.968Z",
String (Date-time)

Date the user was first created in Tempo (across all accounts)

        "email": "[email protected]",
String (Email)

Users will use this email to log in and receive invite notifications.

        "id": "77c8a907-40b7-40ab-91ad-8034df0fa7a0",
String (Uuid)
        "name": "Test User",
String
        roles: [
Array
          {
          { ... }
Object

Roles

            "accountId": "ad032f79-fa7e-45b6-a31d-10a4e43bd69b",
String
            "capabilities": {
            "capabilities": { ... }
Object
              "default": {
              "default": { ... }
Object
                "*": true
Boolean
              }
            },
            "createdAt": "2016-07-17T22:44:35.683Z",
String
            "id": "9ad68f5d-c4bb-4db4-870b-c688afcbb1f3",
String
            "name": "Admin",
String
            "system": "admin"
String
          }
        ]
        teams: [
Array
          {
          { ... }
Object

Teams

            "accountId": "ad032f79-fa7e-45b6-a31d-10a4e43bd69b",
String
            "createdAt": "2016-07-17T22:44:35.763Z",
String
            "id": "843cd093-a038-44a4-b1f2-6caad7cfe49a",
String
            "name": "Staff"
String
          }
        ]
      }
    }
  ]
  "display": {
  "display": { ... }
Object
    "title": "Joe API",
String

The first value on the record by field order

    "subtitle": "[email protected]"
String

The second value on the record by field order

  }
}

Retrieve Search Results

Open in API Explorer
GET /types/:type/search

Returns a list of search results based on the provided search criteria. You can paginate through this data.

Example Request

Format:
curl --request GET \
  --url 'https://api.kepla.com/v1/types/:type/search?offset=0&limit=50&orderBy=createdAt&order=desc&q=example%2540example.com' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer YOUR API KEY HERE'
require 'uri'
require 'net/http'

url = URI("https://api.kepla.com/v1/types/:type/search?offset=0&limit=50&orderBy=createdAt&order=desc&q=example%2540example.com")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer YOUR API KEY HERE'

response = http.request(request)
puts response.read_body
var http = require("https");

var options = {
  "method": "GET",
  "hostname": "api.kepla.com",
  "port": null,
  "path": "/v1/types/:type/search?offset=0&limit=50&orderBy=createdAt&order=desc&q=example%2540example.com",
  "headers": {
    "accept": "application/json",
    "authorization": "Bearer YOUR API KEY HERE"
  }
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();
import http.client

conn = http.client.HTTPSConnection("api.kepla.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer YOUR API KEY HERE"
    }

conn.request("GET", "/v1/types/:type/search?offset=0&limit=50&orderBy=createdAt&order=desc&q=example%2540example.com", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://api.kepla.com/v1/types/:type/search?offset=0&limit=50&orderBy=createdAt&order=desc&q=example%2540example.com",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer YOUR API KEY HERE"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
package main

import (
	"fmt"
	"net/http"
	"io/ioutil"
)

func main() {

	url := "https://api.kepla.com/v1/types/:type/search?offset=0&limit=50&orderBy=createdAt&order=desc&q=example%2540example.com"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("accept", "application/json")
	req.Header.Add("authorization", "Bearer YOUR API KEY HERE")

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

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

	fmt.Println(res)
	fmt.Println(string(body))

}

Path Parameters

Name Type Required Description Example
type String (uuid) Required

The type ID to search

04fe9a97-a579-43c5-bb1a-58ed29bf0a6a

Query Parameters

Name Type Required Description Example
offset Integer Optional

The number of results to skip from the start of the collection

0
limit Integer Optional

The maximum number of results to return

50
orderBy String Optional

The field ID to order results by. This is passed through to Elasticsearch, so you could theoretically order on activity or transaction values. By default it will return results in order of relevance.

createdAt
order String Optional

The direction to order results

desc
q String Optional

A query string to search for. This uses Elasticsearch's query string field and supports full query string syntax

example%40example.com

Request Body

Name Type Required Description Example
payload Object Optional

This endpoint will also accept POST requests with an Elasticsearch query object. You can develop your query from the fields returned in a basic search query. Most data is tokenized in Elasticsearch, so if you're querying something like emails it's best to use the .raw version of the field. For instance: {fieldId}.raw: "My value".

{
  "query": {
  "query": { ... }
Object
    "match": {
    "match": { ... }
Object
      "{fieldId}": "this is an elasticsearch example"
String
    }
  }
}

Responses

200 Success (Empty Response)