Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
143 lines (111 sloc) 6.07 KB


Welcome to, if you're a developer and you are interested in making apps, services or bots you'll find information here on how to interact with the API.

Note: You won't find the source code for here, the project is not open source and there are no plans to do publish the code yet

If you find any bugs or have any suggestions at all, feel free to open an issue and obviously any PRs to contribute towards this documentation are also welcome!


Satoshi's place is a type of Lightning Network powered app (Lapp) that runs an open, permissionless and collaborative art board. Each pixel costs 1 satoshi to paint and can be painted over and over again. If you haven't seen it yet, go check it out first.

The aim of the project is to give everyone a fun, easy and cheap way to experience the power of the Bitcoin Lightning Network. But there's more to it, with the advent of microstransactions and programmatic money, we can actually build Lapps that interact with each other and even provide value added services. In the case of, some of the interesting things to build are:


  • Upload and draw pictures
  • Protect a drawing
  • Animate a drawing


  • Different paint brush sizes
  • Spray paint
  • Shapes (circles, rectangles, stars)


  • Activity heatmaps
  • General stats (i.e. txs/day, pixels/day)
  • Timelapses

All of ideas above can be implemented today in some form or another with the existing API. They can be built as separate services / websites / apps which can even monetize themselves by creating their own lightning invoices with a surchage for the service they provide.

If you need to setup a lightning network node, take a look at the excellent lnd and c-lightning.


The endpoint for the mainnet API lives at There is also a testnet version - you can use it to experiment with testnet coins before going for the real thing. Both APIs linked to and respectively.

The whole API is built using websockets (^1.7.4). Here's a javascript example on how to setup a connection and subscribing to the events we expect to receive:

const io = require('')

const socket = io(API_URI)

// Listen for errors
socket.on('error', ({ message }) => {
  // Requests are rate limited by IP Address at 10 requests per second.
  // You might get an error returned here.

// Wait for connection to open before setting up event listeners
socket.on('connect', a => {
  console.log('API Socket connection established with id',
  // Subscribe to events
  socket.on('GET_LATEST_PIXELS_RESULT', handleGetLatestPixelsResult)
  socket.on('NEW_ORDER_RESULT', handleNewOrderResult)
  socket.on('ORDER_SETTLED', handleOrderSettled)
  socket.on('GET_SETTINGS_RESULT', handleGetSettingsResult)

// Here's two examples on how you send a request, the response will be
// in the callbacks above.
socket.emit('NEW_ORDER', pixelsArray)

There are 3 events that you can send and 4 you can listen to, we'll go over them now. All send + receive events, except for ORDER_SETTLED, are only between a single client and the server. You socket session ID is what allows the server to know who to respond to.

Send Events


Request an image uri for the latest state of the board. No data needs to be sent. The response will be received in GET_LATEST_PIXELS_RESULT.


Request settings like invoice expiry, allowed colors etc. No data needs to be sent. The response will be received in GET_SETTINGS_RESULT.


When you want to draw something, send a request with this event and an array of objects like:

    coordinates: [0, 0],
    color: '#ffffff'

where coordinates is the x, y position in the board (min: 0, max: 1000 for both values), and color is one of the allowed colors received in the settings, in web hex format. Each object represents a pixel, there's a limit to the number of pixels you can submit in each order, this is determined by the orderPixelsLimit value in settings.

Receive Events

All receive events have a payload in the shape of { data: ..., error: ... }, if error is set it will be a string with a message about an error that occured. The stuff you'll care about will be in data.


Received after making a GET_LATEST_PIXELS request. Contains a base64 png image uri that represents the canvas in its current state.


Received after making a GET_SETTINGS request. Example data object:

  boardLength: 1000,
  colors: ['#ffffff', '#e4e4e4', ...],
  invoiceExpiry: 600,
  orderPixelsLimit: 250000,
  pricePerPixel: 1

Note: There are 16 colors available to use.


Received after making a successful order. Contains the generated lightning payment request which you will pay to finalize your drawing. Example data:

	data: 'lnbc110n1pdjpn47pp5up...'


This event is used to notify all users that an update has occured on the board. data will look like this:

  image: 'data:image/png;base64,iVBOR...',
  paymentRequest: 'lnbc110n1pdjpn47pp5up...',
  pixelsPaintedCount: 29,
  sessionId: "ck0ehHuJ0Y2fLEMBAARS" // The session id of the user who just paid, this is used in lieu of a username to display in the hud.


This event is used to notify all users of the latest statistics about the game. data will look like this:

  pixelsPerDay: 1636761,
  transactionsPerDay: 857