Integrating Eph and API/SDK reference

letting you get up and running in minutes.

Authentication Crash Course

When to use your Public API Key

You should use your public API key for the SDK and any client-side API requests. It’s safe to expose this key to application users, but remember the Eph Terms of Service state “[Do not] reveal Eph public API keys by showing them in any user interface or making them clearly readable in unobfuscated code”. This key has limited permissions; for example, you (or someone else) cannot delete tracks or update Smart Contracts. For more information, see API Reference > Authentication by API Key.

When to use your Private API Key

You should use your private API key for any server-side requests. Never expose your private key! It can be used to delete tracks and update Smart Contracts.

When to use E-mail/Password

Eph also allows you to authenticate with an e-mail/password log in. Like your private key, this authentication method has no restrictions, so it goes without saying that revealing or sharing Eph passwords is a bad idea. For more information, see API Reference > Authentication by E-mail/Password.

Getting Started with Eph SDK

Currently, the SDK executes Smart Contracts in JavaScript through a Universal JavaScript virtual machine. You can use this SDK in Node.js or in the browser — in fact any environment that’s connected to the Internet and understands ES5. We’re working on the ability to search Eph for tracks, play tracks through HTML5 Audio and more.

Step 1: Install

Node.js

Get it from npm:

npm install euphoric-adventures-sdk --save

Require it:

const euphoricAdventuresSDK = require('euphoric-adventures-sdk')

For the most up to date version when you npm install, you can reference the GitHub repo instead of the official npm package:

npm install EuphoricAdventures/euphoric-adventures-sdk --save

Browser

For the most up to date version, simply include our hosted copy:

<script src="https://euphoricadventur.es/sdk.js"></script>

The SDK is now available as euphoricAdventuresSDK on the window object.

You may experience build time issues if you install the SDK from npm and require() it in a Babel/Browserify/Webpack set up, as the SDK struggles to identify whether it is in a browser context and will throw an error because some Node.js dependencies appear to be missing. However, it will still work at run time.

Step 2: Set Public API Key

Log in to Euphoria and go to the ‘Me’ tab find to your public API key.

To make sure the SDK has fully loaded, listen for the window load event. Then set your API public key:

window.addEventListener('load', function () { window.euphoricAdventuresSDK.setApiKeyPublic('xyz') })

Step 3: Get Tracks

getTracks returns a Promise that resolves with all the tracks on Eph. Let’s log the tracks:

window.addEventListener('load', function () { window.euphoricAdventuresSDK.setApiKeyPublic('xyz') window.euphoricAdventuresSDK.getTracks() .then(function (tracks) { console.log('[example] tracks', tracks) }) .catch(function (error) { console.error('[example] could not get tracks', error) }) })

Step 3: Play Track

Add an element to your page which will contain the player:

<div id="player-here"></div>

Pick the first track on Eph and pass it to playTrack:

window.addEventListener('load', function () { window.euphoricAdventuresSDK.setApiKeyPublic('xyz') window.euphoricAdventuresSDK.getTracks() .then(function (tracks) { console.log('[example] tracks', tracks) var format = 'SoundAAC' var track = tracks.shift() window.euphoricAdventuresSDK.playTrack(track, format, document.getElementById('player-here')) }) .catch(function (error) { console.error('[example] could not get tracks', error) }) })

(Optional) Step 4: Execute a Smart Contract

To understand how playTrack works, let’s execute a Smart Contract by hand.

Pick the first track on Eph, execute the smart contract (to get a streamable URL) then create a HTML5 Audio element to play it:

window.addEventListener('load', function () { window.euphoricAdventuresSDK.setApiKeyPublic('xyz') window.euphoricAdventuresSDK.getTracks() .then(function (tracks) { console.log('[example] tracks', tracks) var format = 'SoundAAC' var track = tracks.shift() var result = window.euphoricAdventuresSDK.executeSmartContract(track.trackId, format, track.compiledSmartContractCode, false) if (result instanceof Error) { console.error('[example] could not execute smart contract', result) } else { console.log('[example] example play track', result.url) var element = document.createElement('audio') element.src = result.url element.controls = true document.body.appendChild(element) element.play() } }) .catch(function (error) { console.error('[example] could not get tracks', error) }) })

Getting Started with Eph API

Step 1: Your first API request

Whilst you can stream music with our JavaScript SDK in just a few minutes, it’s best to completely understand what the SDK is doing by trying out Eph API. We can make all the requests we need with a public API key.

We’re going to be making API requests, so we’ll need a REST client. Insomnia’s our free cross-platform favourite — install Insomnia and open it (we see a lot of people using Postman, too).

In Insomnia, you can create “Workspaces” to keep things organised. Let’s create a new workspace:

Creating a workspace in Insomnia REST client

See how the top left text on purple has changed to the name of your work space? Great! Let’s create a new request:

Creating a request in Insomnia REST client

You can name the request whatever you like. We’re going to make a GET request, so make sure you’ve chosen this in the list:

Creating a request in Insomnia REST client

Let’s make sure we’ve got a connection to Eph by making a request without an API key and watching it fail.

Eph API is currently available at https://api.euphoricadventur.es/v1. We want to GET the tracks on Eph, so the full URL will be:

https://api.euphoricadventur.es/v1/tracks

Paste this into Insomnia’s URL box and press ‘Send’:

Making a request in Insomnia REST client

See how Eph API has returned a 401 error code with the message “we do not support requests without authentication”? Let’s fix that by providing an API key. Remember “We can make all the requests we need with a public API key’? It’s time for your public API key to work some magic.

Log in to Euphoria and go to the ‘Me’ tab find to your public API key.

Choose “Bearer Token” from the “Auth” dropdown, then in the “token” field, enter public: followed by your public API key:

Making a request in Insomnia REST client

Hooray! Now we see all the tracks on Eph:

Making a request in Insomnia REST client

Step 2: Stream a Track

To stream a track, we just need its ID. Looking at the GET /tracks request we just made, we can see each track has a trackId property. Let’s stream the first track with ID 43d5d7a352da8b60c475c4e1252e8d73.

Eph API returns a streamable URL in AAC format by default. To change this, add a ?format= query parameter; see Platform Reference > Formats for more details. For example, to get a stream in MP3 format, use ?format=SoundSonos.

Paste this into Insomnia’s URL box and press ‘Send’:

https://api.euphoricadventur.es/v1/tracks/43d5d7a352da8b60c475c4e1252e8d73/play

Eph API returns a streamable URL. Paste it into your browser to have a listen.

SDK Reference

setApiKeyPublic (apiKeyPublic)

Sets the public API key. If you don’t call this method before playTrack or executeSmartContract, you’ll only be able to play the demo tracks.

It accepts the following arguments:

  • apiKeyPublic: mandatory string.

getTracks ()

Returns a Promise that resolves with an array of all the tracks on Eph.

playTrack (track, format, element)

Executes the track’s smart contract code in a JavaScript virtual machine and plays the track via an inserted HTML5 audio element. The track does not need to belong to you.

It accepts the following arguments:

  • track: mandatory object. This is usually an element from the getTracks call.
  • format: optional string; the default is SoundAAC. See Platform Reference > Formats for more details.
  • element: mandatory HTMLElement. A HTML5 audio element will be added as a child to this element.

The track will play automatically if playTrack is called as a result of user interaction, like a button click.

executeSmartContract (trackId, format, smartContractCode, simulate)

Executes the smart contract code in a JavaScript virtual machine and returns the Smart Contract Result and a streamable URL for the track. The track does not need to belong to you.

It accepts the following arguments:

  • trackId: mandatory string. An Error is returned if the trackId is not acceptable (either not a string, or an empty string).
  • format: optional string; the default is SoundAAC. An Error is returned if the format is not recognised. See Platform Reference > Formats for more details.
  • smartContractCode: mandatory string. An Error is returned if the smartContractCode is not acceptable or does not execute correctly. See Platform Reference > Formats for more details.
  • simulate: optional boolean; the default is false. The Smart Contract Result is not recorded and no streamable URL is returned.

It returns an object containing:

  • smartContractResult: ‘contributor fund allocation map’ (object mapping contributors (keys) to fund allocation share (values))
  • url: One-time streamable URL for the track

API Reference

Authentication by API Key

We support HTTP Bearer authentication, where you send an unencoded API key. You can use your public or private API key to make requests, but remember that public API keys have very limited permissions as they are likely to be exposed to your application users.

Use as Authorization HTTP header

To successfully authenticate, prepend the API key with its type; for example:

  • public:abc
  • private:def

Set the Authorization HTTP header to ‘Bearer ’ plus this string; for example, Bearer public:abc.

Authentication by E-mail/Password

We support HTTP Basic authentication (‘Basic Auth’), where you send an Authorization HTTP header of ‘Basic ’ plus your e-mail and password joined by a : and Base64 encoded.

If you are a Publisher or a Licensee, do not use this method in client-side applications! Even if your backend generates the Base64 encoding, it would be trivial for your frontend users to decode it and use your Eph password.

Base64 Encode E-mail and Password

Let’s imagine your log in details are bob@euphoricadventur.es and password. Joining these with : forms bob@euphoricadventur.es:password.

In JavaScript, use btoa('bob@euphoricadventur.es:password') to Base64 encode the string.

Use as Authorization HTTP header

To successfully authenticate, just set the Authorization HTTP header to ‘Basic ’ plus this string; for example, Basic Ym9iQGV1cGhvcmljYWR2ZW50dXIuZXM6cGFzc3dvcmQ=.

Your Account

GET /me

Returns an object of your Eph account. If you authenticate with a public API key, the response only contains email, firstName, isPublisher and isLicensee properties. If you authenticate with a private API key or Basic Auth (e-mail and password), a full set of properties is returned including your private API key.

PATCH /me

Updates your Eph account. Be careful — this cannot be undone. firstName and email properties are supported; all other properties are ignored. A full set of properties is returned including your private API key.

DELETE /me

Deletes your Eph account. Be careful — this cannot be undone. Contributors and tracks that belong to you are not deleted.

Tracks

GET /me/tracks

Returns an array of tracks on Eph that belong to you.

GET /me/tracks/${trackId}/analytics

Returns an array of play count by day for a track on Eph that belongs to you.

Exactly 100 days of historic data will be returned from the current day. This route caches its response (per track) for exactly 10 minutes.

POST /me/tracks

Creates a track on Eph. It accepts a payload like the following:

{ "observations": "{}", "smartContractMarkup": "{}", "name": "Love at First Sight", "artists": "Kylie Minogue", "file": { "SoundAAC": "https://samples.libav.org/A-codecs/AAC/ct_faac-adts.aac", "SoundSonos": "http://www.sample-videos.com/audio/mp3/crowd-cheering.mp3" } }

PATCH /me/tracks/${trackId}

Updates a track on Eph that belongs to you. Be careful — this cannot be undone.

This route replaces the entire track. You should take a track from /me/tracks, modify one or more of its properties and send the full track as a payload to this route. Missing properties in the payload are replaced with defaults.

DELETE /me/tracks/${trackId}

Deletes a track on Eph that belongs to you. Be careful — this cannot be undone.

GET /tracks

Returns an array of all tracks on Eph.

Contributors

GET /me/contributors

Returns an array of contributors on Eph that belong to you. A full set of properties is returned including the internalName property.

POST /me/contributors

Creates a contributor on Eph. You must provide name and internalName properties.

Be careful — the /contributors route will immediately reveal this contributor to other Publishers and Licensees.

PATCH /me/contributors/${contributorId}

Updates a contributor on Eph that belongs to you. Be careful — this cannot be undone.

This route replaces the entire contributor. You should take a contributor from /me/contributors, modify one or more of its properties, remove the tracks property and send the full contributor as a payload to this route. Missing properties in the payload are replaced with defaults.

DELETE /me/contributors/${contributorId}

Deletes a contributor on Eph that belongs to you. Be careful — this cannot be undone. This contributor will no longer be allocated funds when Smart Contracts are executed. Consider updating Smart Contracts to allocate funds to other contributors for maximum fund allocation.

GET /contributors

Returns an array of all contributors on Eph.

Playback

GET /tracks/${trackId}/play?format=${format}

Returns an object containing a streamable URL for a track and the Smart Contract Result. This route executes the Smart Contract through the SDK’s executeSmartContract method. The track does not need to belong to you.

The format query parameter is optional; the default is SoundAAC.

See ‘Platform Reference’ > ‘Formats’ for more details.

GET /tracks/${trackId}/test?format=${format}

Returns an object containing only the Smart Contract Result, which is not recorded (no streamable URL). This route executes the Smart Contract through the SDK’s executeSmartContract method. The track does not need to belong to you.

The format query parameter is optional; the default is SoundAAC.

See ‘Platform Reference’ > ‘Formats’ for more details.

GET /formats

Returns an array of supported formats.

See ‘Platform Reference’ > ‘Formats’ for more details.

Smart Contract Code Reference

Inputs

The following inputs may be available in the Smart Contract Code. The inputs are available as input object properties, however their availability is not guaranteed — they may be undefined and Smart Contract Code must still elegantly execute in their absence, returning an Error if an input is absolutely necessary to make a decision. The input object and model input are always available. If you rely on these inputs, Licensees’ application users may not be able to stream tracks. For example, applications which use the SDK in Node.js do not provide a url input.

  • model: Currently always standard
  • userAgent: HTTP user agent of the application user (navigator.userAgent)
  • url: URL of the application (window.location.href)

For example:

if (typeof inputs.url === 'string' && inputs.url.indexOf('twitter.com') >= 0) { return new Error('streaming on social networks is not allowed') }

Execution

The program must return an Error or an object

Return an Error to explicitly indicate the Smart Contract’s abstract goals can’t be fulfilled (for example, if the track shouldn’t be streamable in certain regions). If an Error is returned, no funds will be allocated. It’s important to do this so Eph can differentiate between an explicit, ‘intended’ denial (Error) and an error state (non-Error) which is due to a bug in the Smart Contract Code. It’s useful (but not mandatory) to state the denial reason. Licensees decide whether to pass this on to the application user. For example:

return new Error('application user appears to be in Germany')

Return an object to indicate the execution was successful and funds should be allocated. The object must:

  • Be a ‘flat’ object with keys and values that are only one level deep (like a map)
  • Have keys that are contributor IDs on Eph (if a key is not a known contributor ID, no error is reported)
  • Have values that are integers as a share of 100 and in total do not exceed 100 (error checking is strict)

For example:

var allocation = { '1': 50, '2': 50 }; return allocation;

The program must be synchronous

The Smart Contract Code cannot be asynchronous (for example, it cannot make web requests which do not block the main thread). In a future implementation of Eph, the Smart Contract Code will be able to return a Promise which must be resolved or rejected within a timeframe.

The program must be ‘Universal JavaScript’

The virtual machine runs serverside (in Node.js) and in a browser context. Therefore your Smart Contract Code must be executable in all JavaScript environments.

  • Try not to rely on external libraries or tools. External libraries increase the execution time as the entire library code is evaluated every time the Smart Contract Code is executed. They are also not guaranteed to work in all JavaScript environments. For example, frameworks like jQuery don’t make sense in Node.js.
  • Understand the nuances of writing JavaScript that ‘runs everywhere’. Frontend JavaScript engineers often rely on the availability of a global scope (window object) which does not exist in Node.js.
  • Use a linter to avoid edge case errors.
  • Don’t implement logic which attempts to figure out what environment the code is running in. Things like window and document have already been made unavailable for safety, but any good JavaScript engineer could find a way to wreak havoc outside the virtual machine. Doing so would be an obvious breach of the Eph Terms of Service.
  • Write browser-friendly ES5 — the SDK will not transpile your code. Language features like const and => ‘arrow functions’ are not supported in Internet Explorer and other older browsers. Check browser compatibility with caniuse.com even for language features modern JavaScript engineers take for granted.

Platform Reference

Entities

Consumer An end user of Euphoria, Eph’s demonstration product. As every user can log in to Euphoria, Publishers and Licensees are both also Consumers by definition.
Publisher A type of user who uploads tracks to Eph and manages tracks and tracks’ contributors.
Licensee A type of user who integrates Eph into websites and apps to allow end user playback.
Contributor An entity representing a contributor to a song (such as an artist, producer or writer). Publishers manage tracks and tracks’ contributors.

Formats

Name Description Extension
SoundAAC Stereo AAC stream. .aac
SoundDolbyDigital Surround Sound AC3 stream (5.1 at 640kbps). .ac3
SoundSonos Stereo MP3 stream (320kbps). .mp3
SoundSonos3 3 MP3 streams (F: 1 * 320kbps stereo, B: 2 * 128kbps mono). .mp3
SoundSonos4 2 MP3 streams (F: 1 * 320kbps stereo, B: 1 * 128kbps mono). .mp3
VideoMKV Surround Sound video stream (HEVC/H.265, Dolby Digital 5.1 at 640kbps). .mkv
Eph Coming Soon. Unencoded containers which you can encode to Dolby Atmos, DTS:X and more. .eph

Credits & Copyrights

  • Search icon: Created by il Capitano from the Noun Project
  • Dollar icon: Created by Rockicon from the Noun Project
  • DNA icon: Created by Christopher T. Howlett from the Noun Project
  • Play icon: Created by Agni from the Noun Project
  • CD Sleeve icon: Created by Ralf Schmitzer from the Noun Project
  • Format icon: Created by Ralf Schmitzer from the Noun Project
  • Share icon: Created by Ralf Schmitzer from the Noun Project
  • Other icons: Feather, used under the MIT License
  • 4K video comparison: Copyright ambientskies

Dolby, Dolby Audio, and the double-D symbol are trademarks of Dolby Laboratories. DTS is a registered trademarks of DTS, Inc. © DTS, Inc. All Rights Reserved. Sonos and Sonos product names are trademarks or registered trademarks of Sonos, Inc. All Spotify trademarks, service marks, trade names, logos, domain names, and any other features of the Spotify brand are the sole property of Spotify.

Euphoria is not formally associated with or endorsed by Dolby Digital, DTS, Sonos or Spotify.