NAV Navbar
javascript php
  • Introduction
  • User Experience
  • BitTicket Smart Contracts
  • BitTicket Identities
  • Minter & Observer Nodes
  • Connecting to the API
  • Identity API
  • Tickets API
  • Cloning an Observer node
  • Errors
  • Introduction

    Welcome to the BitTicket® Blockchain API Doumentation.

    The BitTicket Blockchain is specified to the Ethereum Virtual Machine, with a permission based consensus mechanism. It is membership-based, so that new transactions and new blocks can only be created by approved member nodes. Third parties with an interest can freely join by becoming an Observer node to validate the integrity and continuity of the blockchain, and as well to verify ticket ownership and detect bad actors.

    We have created the BitTicket Blockchain in response to several trust problems existing in the ticketing industry market. It is important to note how our solution differs from other blockchain ticketing solutions.

    The BitTicket Blockchain:

    It is not:

    User Experience

    This is how BitTicket works from an end users' (event attendee's) perspective;

    1. A user creates a BitTicket Identity on bitticket.io, or has one created for them by a ticketing platform via API.
    2. A user now has a Wallet address, containing an address hash and part of their Identity.
    3. A user purchases (or otherwise requests) a BitTicket and using OAuth connects the ticketing platform to their BitTicket Identity
    4. The BitTicket, via Smart Contract is sent to the user's BitTicket Wallet address. If they wish, they can now validate this ownership using bitticket.io, a third party implementation of our API, or using their own block explorer.
    5. The user now has enough to attend their event. They show their Wallet address (typically by QR code) to the door staff, who can verify that they are owners of the tickets and that their identity matches.
    6. If allowed within Smart Contract rules, the user is able to log into their BitTicket Identity and transfer their ticket to another BitTicket Identity.

    BitTicket Smart Contracts

    BitTicket® Smart Contracts are written in Ethereums' Solidity language and are intended to protect the consumer (event attendee) by hard-coding rules into the BitTicket at inception, so that counterfeiting and touting behaviour is prevented. Further functionality is planned, and can be built to specification.

    Only BitTicket Smart Contracts can be deployed on the system - it is not possible to deploy arbitrary Solidity code on the BitTicket Blockchain.

    BitTicket Identities

    BitTicket® Identities refer to attendee's accounts registered with the BitTicket system. We operate a strict policy of one Identity per real-life person, and each identity is given a score (out of 100) indicating our confidence in relation to this policy. Identities with too low a score should have certain functionalities blocked until they improve their score. An identity is assigned a wallet address, which is used to store BitTickets.

    No personal information is stored on the Blockchain.

    Minter & Observer Nodes

    It is possible to connect to the BitTicket Blockchain by downloading a node to enable local interaction with the Blockchain. This can improve latency, and mitigates risk of depending on our servers during periods of high demand, and allows use in places where bandwidth is limited.

    Observers

    An Observer node is able to download the BitTicket Blockchain, keep it syncronised and inspect it's contents. By using our API and by following our documentation, you will be able to discern Smart Contract rules, you will be able to verify the ownership of tickets, and you can trace ownership history (for example, if the ticket has been transferred after sale).

    An Observer node is not able to write to or modify the Blockchain.

    Minters

    A Minter node with a credited and authorised blockchain address is able to perform all the functions of an Observer node, as well as:

    By using our API, Minters will be able to discover or create BitTicket Identities.

    Spinning up a node is entirely optional as all functionality can be acheived from our API. Furthermore, in most cases the Minter node's potential must be acheived by using our API. We document here what is possible by the Minter node for better understanding of the BitTicket Blockchain's workings. In exceptional circumstances a ticketing provider, venue or artist may be granted a Minter node role.

    Connecting to the API

    Authentication

    To authorize, use this code:

    const api = require('api');
    
    let connection = api.authorize('yourapikeyhere');
    

    Make sure to replace yourapikeyhere with your API key.

    BitTicket API uses API keys to allow access to the API. You can register a new BitTicket API key by getting in touch with us directly about your project; talk@bitticket.io

    BitTicket API expects for the API key to be included in all API requests to the server in an Authorization header that looks like the following:

    Authorization: yourapikeyhere

    Endpoint

    Initialise the connection with the endpoint given alongside your API key. Be sure to always use a secure connection (https).

    https://api-uk1.bitticket.io/

    For development, please use the sandbox address.

    https://sandbox.bitticket.io/

    Identity API

    Checking the existance of an Identity

    Using personal data you have of a user such as an email address, you can request to check the existence of an identity.

    HTTP Request

    GET /identity/find

    Query Parameters

    Parameter Type Description
    email_address string Use the known email address of your user

    Response

    Returns a user reference if successful, or an error response.

    Parameter Type Description
    userReference string The API internal reference for the user

    If we indicate the user has an identity, continue on by authorising your application to the user via OAuth. Otherwise, jump to Create an Identity.

    Connecting with an Identity using OAuth

    BitTicket uses OAuth 2.0 for to connect a user to your application. A user must authorise your application before you can sell them a ticket.

    1. Request an authorization token.

    HTTP Request

    GET /identity/authorize/<userReference>

    URL Parameters

    Parameter Type Description
    userReference string The user reference returned in the earlier /identity/find request

    Response

    Parameter Type Description
    authUrl string The URL to redirect the user, with your parameters appended.

    2. Redirect the user to our authorization window

    Redirect the user to our authorization window, specifying a urlencoded return url, and any further details you would like to request from the user's profile

    HTTP Request

    Location: authUrl&redirect_uri=<returnUrl>&permissions=email_address,full_name,home_address,dateOfBirth,mobile_number,gender

    Return Url's Response

    Returns to the url with Postdata

    Parameter Type Description
    authToken string A token to re-request permissions granted in the original request
    walletAddress hash A hash used often in the ticket API
    userData array An array holding the results of the permissions granted.

    You should now store the authToken locally and securely.

    Create an Identity

    If we indicated the user has no identity, you can create one for them using a POST request.

    POST /identity/create

    Parameter Type Description
    email_address string email address - should be verifyable
    firstname string Forename or first name
    lastname string Surname or last name
    address string A concatenated postal address
    country string 2 letter country code
    dateOfBirth string Format YYYY-MM-DD
    telephone string A telephone number, including country code

    Return Response

    Returns the newly created users' user reference, authToken and wallet address.

    Parameter Type Description
    userReference string The API's internal reference for the user
    authToken string A token to re-request permissions granted in the original request
    walletAddress hash A hash used often in the ticket API

    Request an previously connected Identity

    Sometimes a user may update their personal data, including the walletAddress. You should use your existing authToken to re-request this data before issuing a fresh ticket.

    If the requests fails (401: Not Authorised), the user may have deleted your access via their wallet. You should re-request their Authorisation Token.

    POST /identity/rerequest/<userReference>

    Parameter Type Description
    authToken string A token to re-request permissions granted in the original request

    Return Response

    Parameter Type Description
    walletAddress hash A hash used often in the ticket API
    userData array An array holding the results of the permissions granted.

    Update an Identity

    PUT /identity/<userReference>

    Parameter Type Description
    authToken string (required) A token to write permissions granted in the original request
    email string email address - should be verifyable - user will confirm
    full_name string First name and last name of the user
    address string A concatenated postal address
    country string 2 letter country code
    dateOfBirth string Format YYYY-MM-DD
    telephone string A telephone number, including country code

    Tickets API

    Create a ticket batch

    POST /tickets/create/<smartContract>/<quantity> smartContract | int | Use the developer portal to find your most relevant smart contract. Use 'ClassicAssociates' as default.

    Parameter Type Description
    quantity int The amount of tickets the batch will initially contain.
    smartContractParams array POST json data - an array of smart contract-specific variables, pertinant to the chosen smartContract
    eventName string The name of the event (for wallet use)
    eventVenue string The name of the venue (for wallet use)
    ticketType string The type of the ticket (for example, 'VIP') (for wallet use)
    eventStartDate int The start date of the event, as a Unix timestamp

    smartContractParams Parameter | Type | Description --------- | ---- | ----------- maxPerCustomer | int | The maximum tickets of this type that one wallet is allowed to hold.

    Return Response

    Parameter Type Description
    ticketsAddress hash The hash denoting the tickets on the blockchain

    Request the remaining root allocation of a ticket batch

    GET /tickets/available/<ticketsAddress>

    Return Response

    Parameter Type Description
    quantity int The amount of unsold tickets
    frozen boolean Whether or not the tickets are currently frozen from sale.

    Adjust the remaining root allocation of a ticket batch

    Issue - Increase Allocation

    PUT /tickets/issue/<ticketsAddress>/<quantity>

    Deissue - Reduce Allocation

    PUT /tickets/deissue/<ticketsAddress>/<quantity>

    Associate with Another Ticketing Provider

    Normally, sale capabilities are restricted to the original tickets' creators. By associating a ticket batch with another ticketing provider, you enable them to sell your tickets.

    Associate Provider

    POST /tickets/associate/<providerId>/<ticketsAddress>/<maxCanSell>

    Disassociate Provider

    POST /tickets/disassociate/<providerId>/<ticketsAddress>

    Check Associate's Remaining Allocation

    GET /tickets/associate/<providerId>/<ticketsAddress>

    Parameter Type Description
    available int The total amount remaining in the ticket address
    maxCanSell int The amount the associate is able to sell

    Hold a ticket

    POST /tickets/hold/<ticketsAddress>/<timeInSeconds>/<quantity>

    Parameter Type Description
    ticketAddress hash The ticket address created earlier
    timeInSeconds int How long to reserve the tickets for while the customer completes their transaction.
    quantity int The amount of tickets to put on hold

    Returns

    Parameter Type Description
    holdHash hash The ticket address created earlier
    quantity int The amount of tickets put on hold
    expires int Unix timestamp when the hold will expire

    Release a held ticket

    To release a held ticket before the hold is due to expire.

    POST /tickets/release/<ticketsAddress>/<holdHash>

    Parameter Type Description
    holdHash hash The hash returned in the previous call.

    Sell a ticket

    POST /tickets/sell/<ticketsAddress>/<holdHash>/<walletAddress>

    Transfer a ticket between two Identities

    PUT /tickets/transfer/<ticketsAddress>/<walletAddressFrom>/<walletAddressTo>/<quantity>

    Freeze and Unfreeze ticket sales and transfers

    By freezing a ticket batch, you are preventing future sales and transfers. This is typically done on the day of an event for example, to prevent touts on doors.

    PUT /tickets/freeze/<ticketsAddress>

    PUT /tickets/unfreeze/<ticketsAddress>

    Listen for ticket transfers

    Refund/return a ticket from an Identity to the original allocation

    You can return a ticket if a refund is due to be processed or a ticket is otherwise void. The ticket will immediately be available for sale, unless the tickets have been frozen.

    PUT /tickets/refund/<ticketsAddress>/<walletAddress>/<quantity>

    Request the list of owners for a ticket batch

    GET /tickets/owners/<ticketsAddress>

    Response

    Returns an array of wallet addresses, and owner hashes.

    Parameter Type Description
    walletAddress hash The corresponding wallet
    ownerHash hash A hash of the user's details
    quantity int The amount of attendees the ticket allows
    scanned tinyint -1: void, 0: not scanned, ≥1: amount scanned
    scannedOn Unix Timestamp If status was set to 1, scannedOn holds the time/date it was scanned.

    Scanning a ticket

    An owner's wallet is a QR code containing the following data: walletAddress|fullName|personalClip

    Your ticket scanning application should read the QR code, and split the string by the pipe ("|") Note: if generating your own QR code, the fullName should have non-ASCII/UTF-8 characters replaced with "?" The last two strings in this new array should be hashed together using the sha256 algorithm, concatenated with pipes ("|"), along with your API secret as a salt. For example,

    sha256( fullName + '|' + PersonalClip + '|' + APISecret )

    This should match the ownerHash, and allow you to verify the ownership of the ticket.

    Your app should present the newly learned Name and dateOfBirth information, quantity and status to the scanner to compare the details against the attendees' Identity.

    Mark the ticket as scanned

    POST /tickets/scan/<ticketsAddress>/<walletAddress>/<quantity>

    Parameter Type Description
    ticketsAddress hash The ticket address created earlier
    walletAddress hash The wallet address holding the tickets ready to scan
    quantity int The amount of tickets ready to scan (cannot exceed wallet's unscanned quantity)

    This will write to the blockchain and mark the ticket as scanned. Once scanned, you cannot unscan the ticket, and a ticket cannot be refunded or transferred.

    Individually verify a known Identity's ownership of a ticket

    GET /tickets/verify/<ticketsAddress>/<walletAddress>

    Returns

    Parameter Type Description
    quantity int The amount of attendees the ticket allows
    status tinyint -1: void, 0: not scanned, ≥1: amount scanned
    scanned Array If status was scanned to ≥1, scanned holds an array the times/amounts the tickets were scanned.
    trace Array An array of arrays detailing the route taken for each individual ticket

    Cloning an Observer node

    Prerequesites

    Clone the node

    Starting & syncing the node

    Interacting with the Observer node

    Errors

    The BitTicket API uses the following error codes:

    Error Code Meaning
    400 Bad Request -- Unspecified error
    401 Unauthorized -- Your API key is wrong.
    403 Forbidden -- Your API key has insufficient privileges for the given request.
    404 Not Found -- The specified request could not be found.
    405 Method Not Allowed
    406 Not Acceptable -- You requested a format that isn't json.
    418 I'm a teapot.
    429 Too Many Requests -- You're requesting too fast.
    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.