NAV Navbar
Node
  • Introduction
  • Authentication
  • Users
  • Bases
  • Tables
  • Columns
  • Records
  • Hooks
  • Files
  • Functions
  • Workflows
  • Errors
  • Introduction

    What is Clay

    Clay is the rapid development environment for hackers. We help you build your next idea fast.

    These docs will walk you through how to use Base to store data, Functions to run backend code without having to set up a server, and Flows to connect and automate services.

    We only have language bindings in Javascript for now. You can view code examples in the dark area to the right.

    Installing the SDK

    To use Clay Base from a web page, use:

    <script src="https://unpkg.com/clay-base-sdk@latest/bundle.js"></script>
    

    The Clay Base SDK can work in both a server environment and a browser environment.

    Yarn

    yarn add clay-base-sdk

    NPM

    npm install clay-base-sdk

    Endpoint

    Clay api runs at https://api.clay.run/v1

    Authentication

    In the SDK, you must use the Private Key & Public Key. To authorize, use this code:

    const Base = require('clay-base-sdk');
    
    // Authenticate with Private Token on Server Side
    Base.init('PRIVATE_TOKEN');
    
    // Authenticate with Public Token on Client Side
    Base.init('PUBLIC_TOKEN')
    

    Make sure to replace PRIVATE_TOKEN with your API key.

    You can register a new Clay API key at clay.run. There are two types of API Keys:

    Clay expects for the API key to be included in all API requests to the API in a header that looks like the following:

    Authorization: Token YOUR_ACCOUNT_TOKEN

    The PUBLIC_KEY only allows for data-reading operations.

    Users

    User object

    {
      "uid": 1,
      "username": "Theo-",
      "email": "theo@clay.com",
      "name": "Théo"
    }
    
    Attribute
    uid The user unique identifier.
    username The unique Clay username.
    email The user's email.
    name The user's name.

    Bases

    POST /v1/bases

    GET /v1/bases

    POST /v1/bases/:id/query

    Base object

    The Base object describe a database in your workspace.

    Example Base Object

    {
        "bid": 1499,
        "uid": "1",
        "name": "a new base",
        "image_icon": "🚀",
        "database_id": "1",
        "private_key": "sk_248c8d429s6c25c541b8",
        "tags": [],
        "public_key": "pk_c640a57dbd14f82a8e86",
        "schema": "user1-a-new-base-ageag094j",
        "updatedAt": "2019-04-19T18:17:51.286Z",
        "createdAt": "2019-04-19T18:17:51.286Z",
        "deletedAt": null,
        "is_public": false
      }
    
    Attribute
    bid Unique identifier for the object.
    uid Unique identifier of the User that created the base.
    name The base's name. Is not unique.
    image_icon The base's icon represented by a emoji.
    database_id The database where your base is stored.
    private_key The private key with write access to the base. Starts with sk_....
    tags An array of strings.
    public_key The public key of the base. Starts with pk_....
    schema The base's schema on the Postgres Server.
    createdAt The base's creation date.
    updatedAt The base's last update date.
    deletedAt The base's deletion date. Always null.
    is_public The privacy policy of the base.

    Create a base

    Creates a new base.

    HTTP Endpoint

    POST /v1/bases

    Body Parameters

    Arguments Description
    name The base's name.
    image_icon The base's icon.

    POST /v1/bases

    {
      "name": "a new base",
      "image_icon": "🚀"
    }
    

    Response

    {
      "success": true,
      "result": {
        "bid": 1499,
        "uid": "1",
        "name": "a new base",
        "image_icon": "🚀",
        "database_id": "1",
        "private_key": "sk_148c3d429a6325c441b8",
        "tags": [],
        "public_key": "pk_c640a17b3d1df82a6686",
        "schema": "user1-a-new-base-ageag094j",
        "updatedAt": "2019-04-19T18:17:51.286Z",
        "createdAt": "2019-04-19T18:17:51.286Z",
        "deletedAt": null,
        "is_public": false
      },
      "timing": 1766
    }
    

    List all bases

    Lists all the bases in your workspace. In addition an array of users having access to that base is returned.

    HTTP Endpoint

    GET /v1/bases

    GET /v1/bases

    {
      "success": true,
      "result": [
        {
          "bid": 1499,
          "uid": "1",
          "name": "a new base",
          "database_id": "1",
          "schema": "user1-a-new-base-ageag094j",
          "image_icon": "🚀",
          "private_key": "sk_148c3d429a6325c441b8",
          "public_key": "pk_c640a17b3d1df82a6686",
          "tags": [],
          "createdAt": "2019-04-19T18:17:51.286Z",
          "updatedAt": "2019-04-19T18:17:51.286Z",
          "deletedAt": null,
          "access": [
            {
              "uaid": 5443,
              "object_type": "base",
              "object_id": "1499",
              "user_type": "user",
              "user_id": "1",
              "access": "owner",
              "createdAt": "2019-04-19T18:17:51.290Z",
              "updatedAt": "2019-04-19T18:17:51.290Z",
              "deletedAt": null,
              "user": {
                "username": "Theo-",
                "uid": "1",
                "profile_picture": "https://avatars0.githubusercontent.com/u/7581961?v=4",
                "name": "Théo"
              }
            }
          ]
        },
        {...},
        {...}
      }
    ]
    

    SQL queries

    POST /v1/bases/:id/query

    {
      "query": "select * from articles"
    }
    

    Response

    {
      "success": true,
      "count": 2,
      "result": [
        {
          "objectId": 10,
          "content": "Awesome content",
          "author": "John Doe"
        },
        {
          "objectId": 11,
          "content": "A good article",
          "author": "John Doe"
        }
      ]
    }
    

    Raw query

    const Base = require('clay-base-sdk');
    
    Base.init('PRIVATE_TOKEN')
    
    Base.query('SELECT * FROM users').then(users => {
      // magic here
    })
    

    Run a custom SQL query on a base.

    HTTP Endpoint

    POST /v1/bases/:id/query

    Body Parameters

    Parameter Default Description
    query required The raw query to run

    Tables

    POST /v1/bases/:id/tables

    GET /v1/bases/:id/tables

    DELETE /v1/bases/:id/tables/:name

    Table object

    {
      "tid": 132750,
      "bid": 139,
      "name": "emails",
      "createdAt": "2018-07-03T15:21:45.275Z",
      "updatedAt": "2018-08-08T02:01:37.148Z",
      "deletedAt": null,
    }
    
    Attribute
    tid Table unique identifier.
    bid Base unique identifier.
    name The table's name.
    createdAt The table's creation date.
    updatedAt Last time the table was updated.
    deletedAt Always null.

    Create a Table

    POST /v1/bases/:id/tables

    {
        "name": "New Table",
        "columns": [
            // OPTIONAL
            // array of Columns Objects
        ]
    }
    

    Response

    {
        "success": true,
        "result": {
            "name": "Table 1"
        },
        "timing": 50
    }
    

    Create a new table in a base. All tables have 3 mandatory fields necessary for Base. These fields are created automatically. They cannot be modified, nor deleted:

    Column Name Type Description
    objectId string A unique object id.
    created_at timestamp with time zone Records the time at which a record was created.
    updated_at timestamp with time zone Records the time of the last modification of that record.

    HTTP Endpoint

    POST /v1/bases/:id/tables

    Body Parameters

    Parameter Default Description
    name required The name of the new table.
    columns [] A list of columns to be created in addition to the 3 mandatory columns. See Column Section.

    List all Tables

    GET /v1/bases/:id/tables

    {
        "success":true,
        "result": [
            {
                "tid": 132750,
                "bid": 139,
                "name": "emails",
                "createdAt": "2018-07-03T15:21:45.275Z",
                "updatedAt": "2018-08-08T02:01:37.148Z",
                "deletedAt": null,
            },
            {
                "tid": 133042,
                "bid": 139,
                "name": "emails2",
                "createdAt": "2018-07-05T14:49:13.534Z",
                "updatedAt": "2018-07-05T14:49:13.534Z",
                "deletedAt": null
            }
        ],
        "count": 5,
        "timing": 45
    }
    

    Retrieve the list of tables in a base.

    HTTP Endpoint

    GET /v1/bases/:id/tables

    Delete a Table

    DELETE /v1/bases/:id/tables/:name

    {
        "success": true,
        "result": {}
    }
    

    Delete a table from a Base. This action is not reversible. Be careful.

    HTTP Endpoint

    DELETE /v1/bases/:id/tables/:name

    Query Parameter

    Parameter Default Description
    name required The name of the new table.

    Columns

    POST /v1/bases/:id/tables/:table_name/columns

    GET /v1/bases/:id/tables/:table_name/describe

    POST /v1/bases/:id/tables/:table_name/columns/:column_name

    POST /v1/bases/:id/tables/:table_name/columns/:column_name/convert

    DELETE /v1/bases/:id/tables/:table_name/columns/:column_name

    Column object

    {
      "cid": 26320,
      "type": "checkbox",
      "name": "new-column-name",
      "ordinal_position": 6,
      "px_size": "200",
      "type_specific": null
    }
    
    Attribute
    cid The column's unique identifier.
    type The column's type. See the list of types above.
    name The column's name.
    ordinal_position The column's position in the table.
    px_size The column's width on the user interface.
    type_specific Type specific data based on the column type. For example, the type multireference requires the name of the reference table.

    Types

    This is the list of available column types on Base.

    Parameter Description
    multiselect Multi-select picker field. It is an array of strings.
    singleselect Single select picker field. Represented as a string.
    text Postgres text field.
    integer Floating point field.
    date Postgres date field.
    jsonb Postgres jsonb field.
    url Text field that enforces URL values.
    imageurl Text field that enforces Image URL values.
    reference Single reference to another table.
    multireference Array of references to another table.
    file File type. See the File section.
    jsonfield Extracted field from a jsonb or computed column.
    checkbox True/false field.

    Create a column

    POST /v1/bases/:base_id/tables/:table_name/columns

    {
        "name": "json_field",
        "type": "jsonb",
        "defaultValue": null,
        "extra": {
            // This must be filled for the `reference` types
            "table": "",
            // This specifies which field to show in the UI for `reference` type
            "displayKey": "",
            // Inputs for Computed Columns
            "inputs": {
                "input1": 3242
            }
        },
        "unique": false
    }
    

    Response

    {
        "success": true,
        "result": {
            "cid": 4741,
            "bid": 147,
            "table_name": "Table 1",
            "column_name": "json_field",
            "type": "jsonb",
            "px_size": "200",
            "ordinal_position": 6,
            "type_specific": {
                "table": "",
                "displayKey": "",
                "column": "",
                "inputs": {
                    "input1": 3242
                }
            },
            "updatedAt": "2018-08-11T03:37:18.930Z",
            "createdAt": "2018-08-11T03:37:18.930Z",
            "deletedAt": null
        },
        "timing":54
    }
    

    Add a column to an existing table.

    HTTP Endpoint

    POST /v1/bases/:id/tables/:table_name/columns

    Query Parameters

    Parameter Default Description
    base_id required The base unique identifier.
    table_name required The table name.

    Body Parameters

    Parameter Default Description
    name required The name of the new column.
    type required The type of the new table. See types below.
    defaultValue NULL The defaultValue if when inserting NULL values. Or the value that will be applied for existing records.
    extra {} Extra information used by the Base backend.
    unique FALSE whether Base should create a UNIQ constraint on this column making duplicate values illegal.

    List all columns

    GET /v1/bases/:base_id/tables/:table_name/describe

    {
        "success":true,
        "result": [
            {
                "cid": 1,
                "type":"text",
                "name":"description",
                "ordinal_position":2,
                "px_size":"200",
                "type_specific": null
            },
            {
                "cid": 2,
                "type":"text",
                "name":"objectId",
                "ordinal_position":0,
                "px_size":"200",
                "type_specific": null
            },
            {
                "cid": 3,
                "type":"timestamp with time zone",
                "name":"updated_at",
                "ordinal_position":4,
                "px_size":"200",
                "type_specific": null
            },
            {
                "cid": 4,
                "type":"timestamp with time zone",
                "name":"created_at",
                "ordinal_position":3,
                "px_size":"200",
                "type_specific": null
            }
        ],
        "count": 5,
        "timing": 5
    }
    

    Get the columns for a table. Returns a list of columns.

    HTTP Endpoint

    GET /v1/bases/:id/tables/:table_name/describe

    Query Parameters

    Parameter Default Description
    base_id required The base unique identifier.
    table_name required The table name.

    Column Object

    Field Type Description
    cid integer The Column ID. It is unique.
    type string The column type.
    name string The column display name.
    ordinal_position integer The column position in the table. (1 = first column).
    px_size integer Pixel width size of the column in the table.
    type_specific json Specific information for the column. For example, this is where the table name is stored for pointers.

    type_specific is a JSONB type used to store extra information for specific types. For instance, linked records us type_specific.table to keep track of the other table.

    Computed columns use type_specific.inputs to keep track of inputs. It is a object mapping input name to column id.

    Rename a column

    POST /v1/bases/:base_id/tables/:table_name/columns/:column_name

    { "newName": "new-column-name" }
    

    Response

    {
      "success": true,
      "result": [
        {
          "cid": 26320,
          "type": "checkbox",
          "name": "new-column-name",
          "ordinal_position": 6,
          "px_size": "200",
          "type_specific": null
        },
        { ... },
        { ... }
      ],
      "count": 6,
      "timing": 60
    }
    

    HTTP Endpoint

    POST /v1/bases/:id/tables/:table_name/columns/:column_name

    Query Parameters

    Parameter Default Description
    base_id required The base unique identifier.
    table_name required The table name.
    column_name required The name of the column to rename.

    Body

    Argument
    newName The column's new name.

    Convert a column type

    POST /v1/bases/:base_id/tables/:table_name/columns/:column_name/convert

    {
      "new_type":"checkbox",
    }
    

    Response

    {
      "success": true,
      "result": [
        {
          "cid": 22519,
          "type": "checkbox",
          "name": "converted-integer",
          "ordinal_position": 6,
          "px_size": "200",
          "type_specific": null
        },
        { ... },
        { ... }
      ],
      "count": 6,
      "timing": 148
    }
    

    Attempts to convert a column from its current type to a new type. If the conversion is unsuccessful, all changes are rolled back. Returns a list of the new columns.

    HTTP Endpoint

    POST /v1/bases/:id/tables/:table_name/columns/:column_name/convert

    Query Parameters

    Parameter Default Description
    base_id required The base unique identifier.
    table_name required The table name.
    column_name required The name of the column to convert.

    Body

    Argument
    new_type The new column's type.
    force Sometimes conversion are impossible. In this case, use force to erase the column and change the type. By default false.

    Delete a column

    DELETE /v1/bases/:base_id/tables/:table_name/columns/:column_name

    {
        "success": true,
        "result": {},
        "timing": 8
    }
    

    Delete a specific column from a table.

    HTTP Endpoint

    DELETE /v1/bases/:id/tables/:table_name/columns/:column_name

    Query Parameters

    Parameter Default Description
    base_id required The base unique identifier.
    table_name required The table name to delete the column from.
    column_name required The name of the column to delete.

    Records

    POST /v1/bases/:id/insert

    POST /v1/bases/:bid/find

    POST /v1/bases/:bid/update

    POST /v1/bases/:bid/delete

    Create record(s)

    POST /v1/bases/:id/insert

    {
      "table": "articles",
      "values": {
        "content": "The article body",
        "author": "Awesome reporter"
      }
    }
    

    Response

    {
      "success": true,
      "result": {
        "objectId": 11,
        "content": "The article body",
        "author": "Awesome reporter"
      }
    }
    

    Insert objects

    const Base = require('clay-base-sdk');
    
    Base.init('PRIVATE_TOKEN')
    
    // Insert a single object
    Base.users.insert({
      email: 'someemail@email.com',
      password: 'hashed_password'
    }).then(user => {
      const { email, password } = user
    })
    
    // Insert multiple objects
    Base.users.insert([
      {
        email: 'someemail@email.com',
        password: 'hashed_password'
      },
      {
        email: 'secondemail@email.com',
        password: 'second_hashed_password'
      }
    ]).then(([user1, user2]) => {
      // User are created
    })
    

    HTTP Endpoint

    POST /v1/bases/:id/insert

    Body Parameters

    Parameter Default Description
    table required The name of table to insert into in utf8 format.
    values required Dictionary of values for the new record OR an array of records to insert.

    Find records

    POST /v1/bases/:id/find

    {
      "where": {
        "somefield": "value"
      },
      "limit": 30,
      "order": "created_at DESC"
    }
    

    Response

    {
      "success": true,
      "result": [
        {
          "field": "record1"
        },
        {
          "field": "record2"
        },
        {
          "field": "record3"
        }
      ]
    }
    

    Query Records with the SDK

    const Base = require('clay-base-sdk');
    
    Base.init('PRIVATE_TOKEN')
    
    // Query a single record from a table
    Base.users.findOne({
      where: {
        email: 'someemail@bitcoin.com'
      },
      order: [
        ['created_at', 'DESC']
      ]
    }).then(user => {
    
      // If no records are found, null is returned
      if(user == null){
        // Handle when nothing is found
      }
      else{
        // Do something with the found record
        const { email, password } = user
      }
    
    })
    
    // Query multiple records from a table
    Base.users.findAll({
      where: {
        deleted_at: { $null: true }
      },
      // Limit the number of records returned
      // default to 30.
      limit: 0
    }).then(users => {
    
      // To get the count of how many objects were returned.   
      const usersCountFound = users.length
    
      // If none were found then users.length == 0   
      if(users.length == 0){
        // Handle when nothing is found
      }
      else{
        // Access the values of a retrieved record
        users[0].values()
      }
    
    })
    
    // Query all records from a table
    Base.users.findAll().then(users => {
    
      // To get the count of how many objects were returned.   
      const usersCountFound = users.length
    
      // If none were found then users.length == 0   
      if(users.length == 0){
        // Handle when nothing is found
      }
      else{
        // Access the values of a retrieved record
        users[0].values()
      }
    
    })
    
    // Pagination with Base
    Base.users.findAll().then(users => {
      return users.nextPage()
    }).then(secondPage => {
      return secondPage.nextPage()
    }).then(thirdPage => {
      // and so on...
    })
    
    // Use selectors
    Base.users.findAll({
      where: {
        connections: {
          // Greater than
          $gt: 2,
          // Greater or equal
          $gte: 3,
          // Less than
          $lt: 5,
          // Less or equal
          $lte: 4,
          // Like
          $like: 3,
          // Not in
          $notIn: [1, 2, 3],
          // In
          $in: [4, 5, 6],
          // JSON: contains
          $contains: 'banana',
          // JSON: is contained
          $containedIn: ['apple', 'banana'],
          // Value is null or not
          $null: false,
          // Not equal to
          $notEq: 'pear',
          // Equal to
          $eq: 'kiwi'
        }
      }
    }).then(users => {
      // To get the count of how many objects were returned
      const accounts = users.length
    
      // To access an individual record from the results:
      console.log(users[0])
    });
    

    Clay base offers a lot of ways to find records.

    HTTP Endpoint

    POST /v1/bases/:bid/find

    Body Parameters

    Parameter Default Description
    config required See below.
    table required Table name.

    All the following parameters are in the config field of the body.

    Parameter Default Description
    where {} A set of values to search for. See examples on the right side.
    limit 30 Maximum number of records to be returned. Maximum 10,000.
    order null Description of how to order the returned records. This is an array of arrays. Example: [["created_at", "DESC"]]
    populate true Populate link records. Can either be true (populate all linked records) or an array for linked records (["linked_record_column", "another_linked_record"])
    attributes * An array of column to query. Example: ["objectId", "created_at", "updated_at"].
    trim false Set it to true to trim any column above 5Bk by default. Set it to an integer to trim any column above that amount of bytes. This is useful to trim computed columns returning large JSON objects.
    page 0 Page number to query. Works with the limit parameter. For example, querying the third page with a limit of 30 will return the records from 60 to 90.

    Update records

    POST /v1/bases/:id/update

    {
      "table": "articles",
      "values": {
        "objectId": 10,
        "content": "new-content"
      }
    }
    

    Response

    {
      "success": true,
      "result": {
        "objectId": 10,
        "content": "new-content",
        "name": "Bananas"
        // ... other fields from the record
      }
    }
    

    Update records

    const Base = require('clay-base-sdk');
    
    Base.init('PRIVATE_TOKEN')
    
    // Query a single record from a table
    Base.users.findOne({
      where: {
        email: 'someemail@bitcoin.com'
      }
    }).then(user => {
      return user.update({
        email: 'new_email@eth.com'
      })
    }).then(updatedUser => {
      const { password } = updatedUser
    })
    
    // Wide update
    Base.users.update({
      // All operators from "Find records"
      // work here.
      where: {
        email: 'someemail@bitcoin.com'
      },
      limit: 1
    }, {
      email: 'new_email@eth.com'
    })
    

    This endpoint updates records in a base.

    HTTP Endpoint

    POST /v1/bases/:bid/update

    Body Parameters

    Parameter Default Description
    table required The name of table in utf8 format
    values required a dictionary of values to update.
    config required a selector object similar to the body config of "Find Records"

    Delete records

    POST /v1/bases/:bid/delete

    {
      "table": "articles",
      "objectId": 10
    }
    

    Response

    {
      "success": true
    }
    

    Destroy Objects

    const Base = require('clay-base-sdk');
    
    // Query a single record from a table
    Base.users.findOne({
      where: {
        email: 'someemail@bitcoin.com'
      }
    }).then(user => {
      return user.destroy()
    }).then(_ => {
      console.log('User was destroyed')
    })
    

    HTTP Endpoint

    POST /v1/bases/:bid/delete

    Body Parameters

    Parameter Default Description
    table required The name of the table in utf8 format
    objectId required the ID of the record to delete

    Hooks

    Database hooks allow you to run custom code on database events. If your endpoints returns anything else than a 200 OK code, the event will be cancelled.

    Common use cases:

    Create a hook

    Example Clay function to validate email on insert

    const emailValidator = require('email-validator')
    
    exports.handler = function(event, done, fail) {
      const record = event.vars
    
      const {
        email
      } = record
    
      if(email == null) {
        return fail('Email must be provided')
      }
    
      if(!emailValidator.validate(email)) {
        return fail('This email doesnt look right')
      }
    
      done(true)
    }
    

    Example body for inserting a user

    {
       "objectId": null, // is determined after insertion
       "email": "someone@clay.run",
       "password": "itphae90h4ap9bn4mckvl",
       "created_at": null,
       "updated_at": null
    }
    

    The insert hook is called every time a record is inserted into a table.

    Clay will make a POST request to the provided url with the record in the POST body.

    If your endpoint returns anything else than a 200 OK response, the record will NOT be inserted into the table.

    Update a hook

    Update works the same way as insert.

    Clay will make a POST request to the provided url with the updated record in the POST body.

    If your endpoint returns anything else than a 200 OK response, the record will NOT be updated.

    Example body for updating a user email

    {
      "row": {
        // updated fields
        "email": "new_email@clay.run"
      },
      // record before update
      "previousRow": {
        "objectId": 3,
        "email": "someone@clay.run",
        "password": "itphae90h4ap9bn4mckvl",
        "created_at": null,
        "updated_at": null
      }
    }
    

    Delete a hook

    Delete works the same way as insert.

    Clay will make a POST request to the provided url with the updated record in the POST body.

    If your endpoint returns anything else than a 200 OK response, the record will NOT be deleted.

    Files

    Upload

    Upload a file

    const Base = require('clay-base-sdk')
    const fs = require('fs')
    
    Base.init('PRIVATE_TOKEN')
    
    const fileStream = fs.createReadStream('./test.txt')
    
    // "uploads" is a table with a column named "file"
    Base.uploads.insert({
      file: fileStream
    }).then(file => {
    
    })
    
    const Base = require('clay-base-sdk')
    const fs = require('fs')
    
    Base.init('PRIVATE_TOKEN')
    
    // suppose input a is <input type="file"/>
    let file = input.files[0]
    let fileReader = new FileReader();
    
    fileReader.readAsDataURL(file)
    
    fileReader.onload = function() {
      console.log(fileReader.result);
      // get the Base64 encoded data
      // e.g. "data:text/html;base64,PGRpdj4KICBUaGlzIGlzIGEgbmV3IEhUTUwKPC9kaXY+Cg=="
    
      var fileToUpload = new Base.File("filename", {
        base64: fileReader.result
      })
    
      Base.uploads.insert({
        file: fileToUpload
      }).then(file => {
        // file uploaded
      })
    });
    

    Base takes care of uploading and storing your files. You can insert files into any column of file type.

    Your files will be stored encrypted into our S3 bucket.

    Retrieve

    const Base = require('clay-base-sdk')
    
    Base.init('PRIVATE_TOKEN')
    
    Base.uploads.find({
      where: {
        objectId: 3
      }
    }).then(upload => {
      const { file } = upload
    
      // File will look like: {
      //   "status":"uploaded"
      //   "storage":"s3"
      //   "download": "https://api.clay.run/v1/files/yyyy/xxxxxxxxxxxxxxxxxxxx"
      //   "read_key":"xxxxxxxxxxxxxxxxxxxx"
      //   "uploadedAt": "2018-04-24T21:41:44.097Z",
      //   "size_in_bytes": 508
      //   "base_upload_id": yyy
      //   "original_file_name": "test.js"
      // }
    })
    

    The SDK will retrieve the file for you and return an object describing the file.

    Field Type Description
    status text Can either be uploading or uploaded.
    storage text The only storage service supported is s3.
    download text The Download URL for the uploaded file. Can be used for the src attributes of images.
    read_key text The last part of the Download URL. There is only one read key per file.
    size_in_bytes integer The size of the file.
    base_upload_id integer The Upload ID, same as the third part of the Download URL.
    original_file_name text The provided file name when uploading.

    Functions

    POST /v1/functions

    POST /v1/functions/:id/deploy

    GET /v1/functions

    POST https://exec.clay.run/:user/:function

    GET /v1/functions/:id/logs

    Function object

    Example of function object

    {
        "fid": 3009,
        "name": "send-gmail-message",
        "aws_name": "Theo--send-gmail-message",
        "inputs": [
          {
            "name": "email",
            "type": "text",
            "description": "Recipient email"
          }
        ],
        "runtime": "nodejs8.10",
        "description": null,
        "package_hash": "d20XDtPtHogB+2dJmqUZF5J4b/lEVUyVX8UpxEZMH7Q=",
        "timeout": 30,
        "memory_size": 1536,
        "owner": 1,
        "is_public": false,
        "createdAt": "2019-03-10T18:00:32.857Z",
        "updatedAt": "2019-03-10T18:28:32.896Z",
        "deletedAt": null,
        "user": {
          "username": "Theo-",
          "uid": "1",
          "profile_picture": "https://avatars0.githubusercontent.com/u/7581961?v=4",
          "name": "Théo"
        }
    }
    
    Parameters
    fid The function unique identifier.
    name The function's name.
    aws_name Internal name for our aws environment.
    inputs An array of inputs defined inside the function's package.json.
    runtime The function's runtime version.
    description The function's description.
    package_hash A hash of the package.json.
    timeout The function's timeout setting.
    memory_size Memory allowed in Mb.
    owner Unique identifier of the user who created the function.
    is_public Privacy setting of the function.
    createdAt The function's creation time.
    updatedAt Last time the function was updated.
    deletedAt Always null.
    user A User object of the creator.

    Create a function

    POST /v1/functions

    {
      "name": "new-function"
    }
    

    Response

    {
      "success": true,
      "result": {
        "fid": 3165,
        "name": "new-function",
        "aws_name": "Theo--new-function",
        "owner": 1,
        "inputs": [
          {
            "name": "sampleInputField",
            "type": "text",
            "description": "This is a sample input"
          }
        ],
        "runtime": "nodejs8.10",
        "timeout": 30,
        "memory_size": 1536,
        "is_public": false,
        "updatedAt": "2019-04-19T19:27:27.422Z",
        "createdAt": "2019-04-19T19:27:27.422Z",
        "description": null,
        "deletedAt": null,
        "package_hash": null,
        "user": {
          "username": "Theo-",
          "uid": "1",
          "profile_picture": "https://avatars0.githubusercontent.com/u/7581961?v=4",
          "name": "Théo"
        }
      },
      "timing": 3413
    }
    

    Create a cloud function.

    HTTP Endpoint

    POST /v1/functions

    Body

    Argument
    name The function's name.

    Deploy a function

    POST /v1/functions/:id/deploy

    {
      "blocks": [
        {
          "name": "index.js",
          "base64Content": "Ly8gUmVhZCB0aGUgZG9jcyB0byBsZWFybiBhYm91dCBmdW5jdGlvbnM6Ci8vIGh0dHBzOi8vZG9jcy5jbGF5LnJ1bi9kb2NzL2Z1bmN0aW9ucy1vdmVydmlldy1hbmQtcXVpY2tzdGFydAoKZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKGV2ZW50LCBkb25lLCBmYWlsKSA9PiB7CiAgICBkb25lKHsKICAgICAgICB2YXJzOiBldmVudC52YXJzLAogICAgICAgIG1lc3NhZ2U6ICJDb25ncmF0cyBvbiBjcmVhdGluZyB5b3VyIGZpcnN0IENsYXkgRnVuY3Rpb24hIFdlIGNhbid0IHdhaXQgdG8gc2VlIHdoYXQgeW91IGJ1aWxkLiBIaSIKICAgIH0pOwp9Cg=="
        },
        {
          "name": "package-lock.json",
          "base64Content": "ewogICJuYW1lIjogIlRoZW8tLW5ldy1mdW5jdGlvbiIsCiAgInZlcnNpb24iOiAiMC4wLjEiLAogICJsb2NrZmlsZVZlcnNpb24iOiAxLAogICJyZXF1aXJlcyI6IHRydWUsCiAgImRlcGVuZGVuY2llcyI6IHsKICAgICJheGlvcyI6IHsKICAgICAgInZlcnNpb24iOiAiMC4xNS4zIiwKICAgICAgInJlc29sdmVkIjogImh0dHBzOi8vcmVnaXN0cnkubnBtanMub3JnL2F4aW9zLy0vYXhpb3MtMC4xNS4zLnRneiIsCiAgICAgICJpbnRlZ3JpdHkiOiAic2hhMS1MSjFqaXk0WkdnanFIV3pKaU9yZGE2Vzl3Rk09IiwKICAgICAgInJlcXVpcmVzIjogewogICAgICAgICJmb2xsb3ctcmVkaXJlY3RzIjogIjEuMC4wIgogICAgICB9CiAgICB9LAogICAgImNsYXktY2xpZW50IjogewogICAgICAidmVyc2lvbiI6ICIwLjIuMSIsCiAgICAgICJyZXNvbHZlZCI6ICJodHRwczovL3JlZ2lzdHJ5Lm5wbWpzLm9yZy9jbGF5LWNsaWVudC8tL2NsYXktY2xpZW50LTAuMi4xLnRneiIsCiAgICAgICJpbnRlZ3JpdHkiOiAic2hhMS10Mko3Vk15b0dQZXNhYWVjZDh3clZ5TU15RjQ9IiwKICAgICAgInJlcXVpcmVzIjogewogICAgICAgICJheGlvcyI6ICIwLjE1LjMiCiAgICAgIH0KICAgIH0sCiAgICAiZGVidWciOiB7CiAgICAgICJ2ZXJzaW9uIjogIjIuNi45IiwKICAgICAgInJlc29sdmVkIjogImh0dHBzOi8vcmVnaXN0cnkubnBtanMub3JnL2RlYnVnLy0vZGVidWctMi42LjkudGd6IiwKICAgICAgImludGVncml0eSI6ICJzaGE1MTItYkM3RWxyZEphSm5QYkFQKzFFb3RZdnFac2IzZWNsNXdpNkJmaTZCSlRVY05vd3A2Y3ZzcGcwalh6blJUS0RqbS9FN0FkZ0ZCVmVBUFZNTmNLR3NITUE9PSIsCiAgICAgICJyZXF1aXJlcyI6IHsKICAgICAgICAibXMiOiAiMi4wLjAiCiAgICAgIH0KICAgIH0sCiAgICAiZm9sbG93LXJlZGlyZWN0cyI6IHsKICAgICAgInZlcnNpb24iOiAiMS4wLjAiLAogICAgICAicmVzb2x2ZWQiOiAiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcvZm9sbG93LXJlZGlyZWN0cy8tL2ZvbGxvdy1yZWRpcmVjdHMtMS4wLjAudGd6IiwKICAgICAgImludGVncml0eSI6ICJzaGExLWpqUXBqTDB1RjI4bFR2L3NkYUhIak1oSi9UYz0iLAogICAgICAicmVxdWlyZXMiOiB7CiAgICAgICAgImRlYnVnIjogIjIuNi45IgogICAgICB9CiAgICB9LAogICAgIm1zIjogewogICAgICAidmVyc2lvbiI6ICIyLjAuMCIsCiAgICAgICJyZXNvbHZlZCI6ICJodHRwczovL3JlZ2lzdHJ5Lm5wbWpzLm9yZy9tcy8tL21zLTIuMC4wLnRneiIsCiAgICAgICJpbnRlZ3JpdHkiOiAic2hhMS1WZ2l1cmZ3QXZtd3BBZDlmbUdGNGplRFZsOGc9IgogICAgfQogIH0KfQo="
        },
        {
          "name": "package.json",
          "base64Content": "ewogICJuYW1lIjogIlRoZW8tLW5ldy1mdW5jdGlvbiIsCiAgImRlc2NyaXB0aW9uIjogIkEgZGVzY3JpcHRpb24gb2YgdGhpcyBmdW5jdGlvbiIsCiAgImF1dGhvcnMiOiAiVGhlby0iLAogICJ2ZXJzaW9uIjogIjAuMC4xIiwKICAicHJpdmF0ZSI6IHRydWUsCiAgInBhcmFtZXRlcnMiOiBbCiAgICB7CiAgICAgICJuYW1lIjogInNhbXBsZUlucHV0RmllbGQiLAogICAgICAidHlwZSI6ICJ0ZXh0IiwKICAgICAgImRlc2NyaXB0aW9uIjogIlRoaXMgaXMgYSBzYW1wbGUgaW5wdXQiCiAgICB9CiAgXSwKICAiZW52cyI6IFsKICAgICJTRUNSRVRfS0VZX05BTUUiCiAgXSwKICAiZGVwZW5kZW5jaWVzIjogewogICAgImNsYXktY2xpZW50IjogIioiCiAgfSwKICAic2NyaXB0cyI6IHsKICAgICJzdGFydCI6ICJub2RlIG5ldy1mdW5jdGlvbiIKICB9Cn0K"
        }
      ]
    }
    

    Response

    {
      "success": true,
      "result": {
        "fid": 3165,
        "name": "new-function",
        "aws_name": "Theo--new-function",
        "inputs": [
          {
            "name": "sampleInputField",
            "type": "text",
            "description": "This is a sample input"
          }
        ],
        "runtime": "nodejs8.10",
        "description": null,
        "package_hash": "yIBfpq0G2i3MpKgoPLzNYlYhq6ASL1E+ewKY0L1fpr4=",
        "timeout": 30,
        "memory_size": 1536,
        "owner": 1,
        "is_public": false,
        "createdAt": "2019-04-19T19:27:27.422Z",
        "updatedAt": "2019-04-19T19:30:10.120Z",
        "deletedAt": null
      },
      "timing": 3836
    }
    

    You can only deploy functions that have previously been created.

    HTTP Endpoint

    POST /v1/functions/:id/deploy

    Body

    Argument
    blocks An array of code blocks.

    Code blocks are base64 encoded files.

    List all functions

    GET /v1/functions

    {
      "success": true,
      "result": [
        {
            "fid": 3009,
            "name": "send-gmail-message",
            "aws_name": "Theo--send-gmail-message",
            "inputs": [
              {
                "name": "email",
                "type": "text",
                "description": "Recipient email"
              }
            ],
            "runtime": "nodejs8.10",
            "description": null,
            "package_hash": "d20XDtPtHogB+2dJmqUZF5J4b/lEVUyVX8UpxEZMH7Q=",
            "timeout": 30,
            "memory_size": 1536,
            "owner": 1,
            "is_public": false,
            "createdAt": "2019-03-10T18:00:32.857Z",
            "updatedAt": "2019-03-10T18:28:32.896Z",
            "deletedAt": null,
            "user": {
              "username": "Theo-",
              "uid": "1",
              "profile_picture": "https://avatars0.githubusercontent.com/u/7581961?v=4",
              "name": "Théo"
            }
        },
        {...},
        {...}
      ]
    }
    

    HTTP Endpoint

    GET /v1/functions

    Call a function

    POST https://exec.clay.run/Theo-/echo

    {
        "hello": "world"
    }
    

    Response

    {
      "vars": {
        "hello": "world"
      },
      "envs": {
        "ENV_VAR_1": "hello world"
      }
    }
    

    Call a fuction from the SDK

    const Clay = require('clay-base-sdk')
    
    Clay.init('PRIVATE_TOKEN or PUBLIC_TOKEN')
    
    // The function Theo/echo just echoes back the payload
    // Learn more at https://www.clay.run/services/Theo/echo
    Clay.run('Theo-/echo', {
      ping: 'pong'
    }).then(result => {
      /**
       * result =
       * { ping: 'pong' }
       * /
    })
    

    The SDK lets you run functions easily from either the front-end or the back-end of your app.

    HTTP Endpoint

    POST https://exec.clay.run/:user/:function

    List function logs

    GET /v1/functions/:id/logs

    {
      "success": true,
      "result": {
        "requests": {
          "9a86afa7-dcf6-4706-b591-f862cfe764ac": [
            {
              "logStreamName": "2019/04/19/[$LATEST]11add30028614be096a405e9fd82a3ce",
              "timestamp": 1555702421575,
              "message": "START RequestId: 9a86afa7-dcf6-4706-b591-f862cfe764ac Version: $LATEST\n",
              "ingestionTime": 1555702421588,
              "eventId": "34693323308281144554961579706210885139795608992612352000"
            }
          ]
        },
        "requestsOrder": [
          "9a86afa7-dcf6-4706-b591-f862cfe764ac"
        ]
      },
      "timing": 786
    }
    

    Get a list of logs.

    HTTP Endpoint

    GET /v1/functions/:id/logs

    Workflows

    POST /v1/workflow

    PATCH /v1/workflow/:id

    POST /v1/workflows/run/:public_key

    GET /v1/workflows

    DELETE /v1/workflows/:id

    Workflow object

    {
      "wid": 667,
      "created_by": 1,
      "name": "my workflow",
      "description": null,
      "public_key": "85001cb8f9k89d2",
      "active": false,
      "createdAt": "2019-04-18T14:24:03.845Z",
      "updatedAt": "2019-04-18T14:24:03.845Z",
      "deletedAt": null
    }
    
    Attribute
    wid The workflow unique identifier.
    created_by The user identifier of the creator.
    name The workflow's name.
    description The workflow's description.
    public_key The workflow's public key. It is needed to run the workflow.
    active Workflow status. Only active workflows can be run.
    createdAt The workflow's creation date.
    updatedAt The last time this workflow was updated.
    deletedAt Always null.

    Create a Workflow (Flow)

    POST /v1/workflow

    {
      "name": "new-workflow"
    }
    

    Response

    {
      "success": true,
      "result": {
        "active": false,
        "wid": 676,
        "name": "new-workflow",
        "created_by": 1,
        "public_key": "d8ce6e90f3497cf",
        "updatedAt": "2019-04-19T20:16:36.513Z",
        "createdAt": "2019-04-19T20:16:36.513Z",
        "deletedAt": null
      },
      "timing": 18
    }
    

    HTTP Endpoint

    POST /v1/workflow

    Body

    Argument
    name The workflow's name.

    Update a workflow

    PATCH /v1/workflows/:id

    {
      "name": "new-workflow-updated",
      "active": true
    }
    

    Response

    {
      "success": true,
      "result": {
        "wid": 677,
        "created_by": 1,
        "name": "new-workflow-updated",
        "public_key": "2b32330e810042d",
        "active": true,
        "createdAt": "2019-04-19T20:20:05.086Z",
        "updatedAt": "2019-04-19T20:21:58.441Z",
        "deletedAt": null
      },
      "timing": 12
    }
    

    HTTP Endpoint

    PATCH /v1/workflow/:id

    Body

    Argument
    name The workflow's new name.
    active Turn on or off a workflow.

    Run a workflow

    POST /v1/workflows/run/:public_key

    {
      "success": true,
      "result": {
        "success": true,
        "type": "async"
      },
      "timing": 2
    }
    

    If the workflow is turned off

    {
      "success": true,
      "result": "Test data has been saved for the triggger step. Turn on the workflow to run the full workflow.",
      "count": 94,
      "timing": 7
    }
    

    HTTP Endpoints

    POST /v1/workflows/run/:public_key

    or

    GET /v1/workflows/run/:public_key

    Body

    If using POST, everything that is passed will be sent to the workflow.

    List all workflows

    GET /v1/workflows

    {
      "success": true,
      "result": [
        {
          "wid": 676,
          "created_by": 1,
          "name": "new-workflow",
          "public_key": "d8ce6e90f3497cf",
          "active": false,
          "createdAt": "2019-04-19T20:16:36.513Z",
          "updatedAt": "2019-04-19T20:16:36.513Z",
          "deletedAt": null,
          "trigger": {
            // Trigger object if any
          }
        },
        {...},
        {...}
      ]
    }  
    

    HTTP Endpoint

    GET /v1/workflows

    Delete a workflow

    DELETE /v1/workflows/:id

    {
      "success": true,
      "result": {},
      "timing": 19
    }
    

    HTTP Endpoint

    DELETE /v1/workflows/:id

    Errors

    The Base API uses the following error codes:

    Error Code Meaning
    400 Bad Request -- Your request is invalid.
    401 Unauthorized -- Your API key is wrong.
    404 Not Found -- The specified resource could not be found.
    429 Too Many Requests
    500 Internal Server Error -- We had a problem with our server. Try again later.
    503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.