Introduction

We have organized our API around REST and utilize object/resource orientated URLs that are predictable. All endpoint responses are returned as JSON, although any official API library uses the language appropriate representation of an object. We also offer a webhook event system which follows the same guide as endpoint responses and all object attributes will be exactly the same.

We require and force all requests to any of Selly's services, including the API, to be served over HTTPS

The Selly API is designed for those interested in developing their products utilizing our platform. Due to the nature of this platform, we rate limit it heavily. The universal rate limit is 150 requests an hour. We plan to offer cheap developer plans to greatly expand the number of requests you can do. Contact us for a quote.

The Selly API Endpoint

https://selly.gg/api

Authentication

You need to be authenticated for all API requests. You can find your API token in your settings page located here.

Headers
X-Auth-Email
string
Your email address
X-Auth-Key
string
API token located here
curl 'https://selly.gg/api/' \
-H 'X-Auth-Email:youremail@email.com' \
-H 'X-Auth-Key:YourKeyHere'

If authentication fails, it will respond with the following and a 403 status.

{
  "status":false,
  "error":["Invalid authentication"]
}

Errors

The error attribute is an array due to some errors being stacked

CodeNameDescription
200OKSuccess
201CreatedCreation successful
400Bad RequestWe could not process that action
401UnauthorizedWe could not authorize/authenticate you
404Not FoundRecord/page could not be found
422UnprocessableParamaters missing/invalid
429Rate LimitedYou have done too many requests
500Internal server errorWe've been notified of an issue

All errors will be returned in a standard format

{
  "status":false,
  "error":["Error message"]
}

Rate Limiting

We use two types of rate limiting. Overall requests are limited to 150 an hour. When hitting this limit you'll have to wait an hour before being able to send a request again. Our other rate limiting is for authentication. Some specific actions will be rate limited separately as well. All rate limits can be expanded by contacting us for a quote for a development plan.

Pagination is available for the index of a object's endpoint, for example https://selly.gg/api/products. Pagination is accomplished by having a page parameter of the wanted page number. The total number of pages will be returned in the header X-Total-Pages

/products

List all products

All products that are not product_type 2 will have a string stating "∞" as the stock.

URL Parameters
page
integer
Paginates 20 results at a time

Lists all your products and their respective details.

curl 'https://selly.gg/api/products' \
-H 'X-Auth-Email:youremail@email.com' \
-H 'X-Auth-Key:YourKeyHere'
[
  {
    "id": "7b84a62b",
    "title": "My awesome product",
    "description": "This is the description",
    "stock": 0,
    "price": "3.99",
    "currency": "USD",
    "product_type": 2,
    "private": false,
    "unlisted": false,
    "seller_note": "",
    "maximum_quantity": null,
    "minimum_quantity": 1,
    "custom": {
      "0": {
        "type": "2",
        "name": "Username",
        "required": true
      }
    },
    "created_at": "2017-03-14T23:27:54.000Z",
    "updated_at": "2017-03-20T16:48:20.000Z"
  },
  {
    "id": "dd834c",
    "title": "This is my awesome product",
    "description": "And the description",
    "stock": 0,
    "price": "3.99",
    "currency": "USD",
    "product_type": 2,
    "private": false,
    "unlisted": false,
    "seller_note": "",
    "maximum_quantity": null,
    "minimum_quantity": 1,
    "custom": {},
    "created_at": "2016-04-08T15:39:48.000Z",
    "updated_at": "2016-11-26T01:13:25.000Z"
  }
]

/products/:id

Get a product's details

Parameters
id
integer
Identity number
curl 'https://selly.gg/api/products/7b84a62b' \
-H 'X-Auth-Email:youremail@email.com' \
-H 'X-Auth-Key:YourKeyHere'
{
    "id": "7b84a62b",
    "title": "My awesome product",
    "description": "This is the description",
    "stock": 0,
    "price": "3.99",
    "currency": "USD",
    "product_type": 2,
    "private": false,
    "unlisted": false,
    "seller_note": "",
    "maximum_quantity": null,
    "minimum_quantity": 1,
    "custom": {
      "0": {
        "type": "2",
        "name": "Username",
        "required": true
      }
    },
    "created_at": "2017-03-14T23:27:54.000Z",
    "updated_at": "2017-03-20T16:48:20.000Z"
}

/orders

List all orders

URL Parameters
page
integer
Paginates 20 results at a time

Lists all your orders and their respective details.

curl 'https://selly.gg/api/orders' \
-H 'X-Auth-Email:youremail@email.com' \
-H 'X-Auth-Key:YourKeyHere'
[
    {
    "id": "89ac7499-efc3-4f5b-a2fd-c00fec6aa480",
    "product_id": "ac24a3",
    "email": "132.26.9.4",
    "ip_address": "80.41.8.199",
    "country_code": "US",
    "user_agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36",
    "value": "0.03",
    "currency": "USD",
    "gateway": "Bitcoin",
    "risk_level": 9,
    "status": 0,
    "delivered": "Unpaid",
    "crypto_value": null,
    "crypto_address": null,
    "referral": "Direct",
    "usd_value": "0.03",
    "exchange_rate": "1.0",
    "custom": {
      "0": "MyUsername"
    },
    "created_at": "2015-06-11T18:32:01.000Z",
    "updated_at": "2017-02-14T17:47:27.000Z"
  },
  {
    "id": "fd87d909-fbfc-466c-964a-5478d5bc066a",
    "product_id": "upgrade",
    "email": "alishia@yahoo.com",
    "ip_address": "88.96.129.5",
    "country_code": "US",
    "user_agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36",
    "value": "0.03",
    "currency": "USD",
    "gateway": "Bitcoin",
    "risk_level": 10,
    "status": 100,
    "delivered": "SERIAL-12345-12345",
    "crypto_value": null,
    "crypto_address": null,
    "referral": "Direct",
    "usd_value": "0.03",
    "exchange_rate": "1.0",
    "custom": {
      "0": "SomeInput"
    },
    "created_at": "2016-11-27T14:20:34.000Z",
    "updated_at": "2016-12-05T21:31:15.000Z"
  }
]

/orders/:id

Get a order's details

Parameters
id
string
The id of the order

Lists details about the specified order.

curl 'https://selly.gg/api/orders/79e118b9-ce58-4952-a1c7-467ca152d8f5' \
-H 'X-Auth-Email:youremail@email.com' \
-H 'X-Auth-Key:YourKeyHere'
{
    "id": "fd87d909-fbfc-466c-964a-5478d5bc066a",
    "product_id": "upgrade",
    "email": "alishia@yahoo.com",
    "ip_address": "88.96.129.5",
    "country_code": "US",
    "user_agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36",
    "value": "0.03",
    "currency": "USD",
    "gateway": "Bitcoin",
    "risk_level": 10,
    "status": 100,
    "delivered": "SERIAL-12345-12345",
    "crypto_value": null,
    "crypto_address": null,
    "referral": "Direct",
    "usd_value": "0.03",
    "exchange_rate": "1.0",
    "custom": {
      "0": "SomeInput"
    },
    "created_at": "2016-11-27T14:20:34.000Z",
    "updated_at": "2016-12-05T21:31:15.000Z"
  }

/exchange/rates

List exchange rates

List current exchange rates used by Selly. All exchange rates are based off United Stated Dollars (USD $) and are updated every 5 minutes.

curl 'https://selly.gg/api/exchange/rates' \
-H 'X-Auth-Email:youremail@email.com' \
-H 'X-Auth-Key:YourKeyHere'
{
  "USD": 1,
  "GBP": 0.80488,
  "EUR": 0.93897,
  "SEK": 8.8712,
  "SGD": 1.4165,
  "AUD": 1.3044,
  "CAD": 1.3079,
  "CHF": 0.99878,
  "CNY": 6.867,
  "BRL": 3.1311
}

Webhooks

Webhooks are a HTTP callback event that is sent to the Webhook URL specified for the affected order. All webhook requests are sent as a POST request and are handled independently from the event, asynchronously.

We recommend when setting the webhook URL on a product, you add a secret parameter to verify the request is genuinely from Selly. An example URL with a secret added in may be https://requestb.in/15rrszg2?secret=thisischeckedbyyou.

The content sent in the webhook is a JSON object of whatever the webhook is related to. If it was a order webhook, the content received would be the same as the individual order API call that can be found here.

Each webhook request contains a webhook_type attribute to identify what the request is for. As we expand our system, more webhook events/types will be added. We plan to offer events for query's being created/replied to, feedback being left and more.

CodeDescription
1Order paid
2Order chargeback
3Dynamic product
4Product out of stock
5Product reached warning stock

Dynamic Products

Dynamic products is a new product type intended for developers. It's built on top of the webhook system and it's purpose is for "dynamic stock". It works by sending a webhook requests with a order object to the specified dynamic URL and whatever said URL returns, that's what will be delivered to the customer. This allows for a whole new subset of products to be completely automated and delivered to the seller immediately.

An example application of this may be generating serials. The seller's dynamic URL endpoint processes the order object and generates a unique serial code and returns it in the response body as Content-Type: text/plain; charset=UTF-8. Do note the response body will be truncated to 500 characters which is more than adequate for anybody's needs.

To ensure that webhooks requests sent to the dynamic URL endpoint is legitimate, make sure you append parameters onto the URL that can be checked in the endpoint. A example dynamic URL may be https://mywebsite.com/endpoint?secret=ThisIsASecret&secret_two=TwoTimesSecretIsTwoTimesAsFunwhere both secret and secret_two are verified by your endpoint. You will only receive requests to the dnynamic URL when the order has already been marked as having a status of complete a.k.a 100.

Lets say the following URL is our Dynamic URL
http://www.mocky.io/v2/58dfa2e81000004001cc15ba
When we go there (POST request) we get the following in plain text:
This is generated server side.
The above is what would be sent to the buyer. We only send what that page displays hence you cannot use a dynamic product for files. Any HTML would also be sent to the buyer as it would consider it as plain text, so make sure you do not render anything but good old plain text.

Examples

Although not much example code can be provided right now, here are a few ideas for how webhooks can be used and have been used by Selly's merchants.

  • Discord/slack bot to notify when a product is low/out of stock or a order is paid/chargedback
  • Email the customer with a generated serial number. Although this partially defeats the purpose of Selly's delivery, we do plan to offer a product type that fetches data from the URL and delivers that data
  • Keeping track of stock

Small example of notifying about orders via Discord

require 'sinatra'
require 'discordrb'

post '/webhook-url' do

  bot = Discordrb::Bot.new token: 'PUTTOKENHERE', client_id: 168123456789123456
  type = params[:webhook_type].to_i

  case type
    # Order paid
    when 1
      bot.send_message(
        'channel-id',
        "#{params[:id]} has been paid - #{params[:value]}"
      )
    # Order chargeback
    when 2
      bot.send_message(
        'channel-id',
        "#{params[:id]} has chargedback - #{params[:value]}"
      )
    else
      # Do nothing
  end

  bot.run
end