API Documentation


Authorization

An application using the Skydeck API must use the OAuth protocol version 1.0 to request authorization from a user to access the user's account.

The OAuth endpoints are

    https://api.skydeck.com/api/oauth/request_token
    https://skydeck.com/oauth/authorize
    https://api.skydeck.com/api/oauth/access_token
            
All requests must be made over SSL, and the only supported signature method is PLAINTEXT. Both GET and POST requests are supported, and OAuth parameters may be passed in the Authorization header or as CGI arguments.

The application requests and is granted a set of capabilities which allow it to perform particular actions on the user's account. The capabilities are

    Usage_read
    Usage_write
    Item_read
    Item_write
    Item_write_source
    Contact_read
    Contact_write
    Contact_rank_ids
            
To use an API call, the application must have been granted the capability for that call. The capabilities needed for each call are given below.

When calling the Request Token endpoint, you must pass in the capabilities your application needs as CGI arguments. For example (removing line breaks):

    https://api.skydeck.com/request_token?
      capability=Usage_read&capability=Usage_write
            

To use the API in a public application, you must register an OAuth consumer. Once you have a consumer key and secret, you must use the OAuth endpoints above to get a request token, have it authorized by the user, and exchange it for an access token, following the OAuth protocol specification.

To use the API on your own account, without registering an OAuth consumer, get a preauthorized access token. (By default this token has all the capabilities.) This access token is authorized against the Skydeck Developer consumer, whose consumer key and secret are (literally)

    skydeck_developer_key
    skydeck_developer_secret
            
For example, once you have gotten an access token access_token with secret access_token_secret, you can retrieve the usage on your account at the following URL (removing line breaks)
    https://api.skydeck.com/api/usage/get?
      oauth_consumer_key=skydeck_developer_key&
      oauth_token=access_token&oauth_signature_method=PLAINTEXT&
      oauth_signature=skydeck_developer_secret%2526access_token_secret&
      oauth_timestamp=&oauth_nonce=
            

General

Most API parameters are passed as CGI arguments. For calls which write some object, the written object is passed as a JSON object in the POST body, with Content-type: application/json.

Responses are always JSON objects. The type of the returned object is given with the following syntax:

numberbuilt-in Javascript number type
stringbuilt-in Javascript string type
date or date/timedate or date/time given Unix-style (seconds since 1/1/1970 00:00:00)
[ type, ... ]Fixed-length Javascript array with elements of the given types
type arrayVariable-length Javascript-array with elements of the given type
{ field : type, ... }Javascript object with the given fields/types
(type1, type2) mapJavascript object mapping fields of type1 to values of type2
type1 | type2either type1 or type2
"String"the literal string "String" (tags used to tell types apart)
namea defined type with name name
type?object of type or possibly null; without ? a type will never be null

All API calls take a version argument. If you don't pass a version you get the current version of the API. The current version of the API is 0.2; it is recommended that you pass version=0.2.

All API calls take a style argument. If style=pretty then the resulting JSON will be pretty-printed; otherwise it will be minified.

All API calls take a callback argument. If callback=foo then the JSON response is returned wrapped in a call to foo; otherwise the JSON response is returned directly.

Usage

Datatypes:

  usage :=                  // returned by /api/usage/get
  {
    voiceUsed : number?,    // minutes used this billing period
    voiceIncluded : limit?, // minutes in plan, or unlimited
    msgUsed : number?,      // messages used this billing period
    msgIncluded : limit?,   // messages in plan, or unlimited
    nextBill : date?,       // date that next billing period begins
    asOf : date/time?,      // date/time as of which data is valid
    uploaded : date/time?   // date/time the data was uploaded
  }

  in_usage :=               // passed to /api/usage/update
  {
    voiceUsed : number?,
    voiceIncluded : limit?,
    msgUsed : number?,
    msgIncluded : limit?,
    nextBill : date?,
    asOf : date/time?,
  }

  limit := [ "Limited", number ] | "Unlimited"
          

API calls:

URL /api/usage/get
Function Returns user's current usage.
CapabilityUsage_read
Returns usage
 
URL /api/usage/update
Function Sets user's current usage.
CapabilityUsage_write
POST body in_usage

Example:

  {
    voiceUsed: 0,
    voiceIncluded: ["Limited", 3958],
    msgUsed: null,
    msgIncluded: null,
    nextBill: 1212562800.0,
    asOf: 1210115580.0,
    uploaded: 1210115608.0
  }
          

Call Log

Datatypes:

  item :=                       // returned by /api/item/get
  {
    id : number,
    kind : item_kind,
    direction : item_direction,
    lineNumber : string,        // number call was billed to
    remoteNumber : string,      // number of the other party on call
    contact : int?,             // ID of contact overriding remoteContact
    lineContact : int?,         // ID of contact with number lineNumber
    remoteContact : int?,       // ID of contact with number remoteNumber
    incurred : date/time,       // Date/time call happened
    tags : string array,        // Tags associated with call
    duration : int,             // Call duration in seconds
    charges : int,              // Call charges in cents
    note : string,
    message : string,           // text message contents, if supplied by the source
    in_inbox : bool,            // true if message is in inbox
    source : string,            // string identifying item source
    source_group : string,      // see in_source_item
    source_key : string         // see in_source_item
  }

  in_item :=                    // passed to /api/item/update
  {
    id : number,
    contact : int?,
    tags : string array,
    note : string
  }

  in_source_item :=             // passed to /api/item/add
  {
    id : number,                // not used, pass -1
    kind : item_kind;
    direction : item_direction;
    lineNumber : string;
    remoteNumber : string;
    incurred : float;
    duration : int;
    charges : int;
    message? : string;          // text message contents, "" if unavailable
    in_inbox? : bool;           // true if message is in inbox
    source_group : string;      // string identifying a group of related items (e.g. a bill)
    source_key : string         // key for duplicate removal (item with preexisting key is not added)
  }

  item_kind := "Call" | "Sms"

  item_direction := "Incoming" | "Outgoing"

  order := "incurred" | "lineNumber" | "remoteNumber" | "duration" |
           "charges" | "direction" | "contact"
          

API calls:

URL /api/item/get
Function Returns items from user's call log.
CapabilityItem_read
Arguments
order? orderSort order
limit? numberLimit number of items returned
query? stringMatch call log query as in application
tag? stringMatch items with given tag
contact? numberMatch items with given contact
lineContact? numberMatch items with given lineContact
remoteContact?numberMatch items with given remoteContact
lineNumber? stringMatch items with given lineNumber
remoteNumber? stringMatch items with given remoteNumber
Returnsitem array
 
URL /api/item/update
Function Sets fields on item in user's call log.
CapabilityItem_write
POST body in_item
 
URL /api/item/tags
Function Gets all item tags for user, with counts.
CapabilityItem_read
Returns (string, int) map
 
URL /api/item/add
Function Adds a list of items to user's call log.
CapabilityItem_write_source
POST body in_source_item array


Address Book

Datatypes:

  contact :=                                          // returned by /api/contact/get
  {
    id : number,
    name : [ string, string, string, string, string ] // prefix, first, middle, last, suffix
    birthday : date?,
    notes : string,
    tags : string array,
    created : date/time,
    updated : date/time,
    numCallsFrom : number,                            // number of calls from contact
    numCallsTo : number,                              // number of calls to contact
    durCallsFrom : number,                            // total duration (in minutes) of calls from contact
    durCallsTo : number,                              // total duration (in minutes) of calls to contact
    numTxtMsgs : number,                              // total number of text messages with contact
    volume : number,                                  // total number of minutes with contact
    balance : number,                                 // ratio of calls from/to contact
    daysSinceLastCall : int,                          // number of days since last call with contact
    firstCallTime : date/time,                        // first call time overall with contact
    lastCallTime : date/time,                         // last call time overall with contact
    callSpan : number,                                // number of days between first and last call
    rank : number?,                                   // Skydeck rank of contact
    bars : number,                                    // number of strength bars
    emails : email array,
    ims : im array,
    phoneNumbers : phoneNumber array,
    postalAddresses : postalAddress array,
    organizations : organization array,
    is_hidden : bool                                  // flag whether contact is hidden
  }

  in_contact :=                                       // passed to /api/contact/{add,update,sync}
  {
    id : number?,  // skydeck.com id, same used in other contact APIs
    name : [ string, string, string, string, string ],
    birthday : date?,
    notes : string,
    tags : string array,
    emails : email array,
    ims : im array,
    phoneNumbers : phoneNumber array,
    postalAddresses : postalAddress array,
    organizations : organization array,
    is_hidden : bool?,   // contact is hidden when this is set true
    localId : string?    // client's local ID for this contact.  Only used in /api/contact/sync.
  }

  email :=
  {
    address : string,
    section : section
  }

  im :=
  {
    address : string,
    protocol : im_protocol,
    section : section
  }

  im_protocol := "AIM" | "GoogleTalk" | "ICQ" | "IRC" | "Jabber" | "MSN" | "Skype" | "Yahoo" | "Other"

  phone_number :=
  {
    number : string,
    kind : pn_kind,
    section : section
  }

  pn_kind := "Fax" | "Mobile" | "Pager" | "Text_msg" | "Voice"

  postal_address :=
  {
    address : string,
    section : section
  }

  organization :=
  {
    name : string,
    title : string,
    section : section
  }

  section := "Personal" | "Work" | "Other"

  ranked_id :=                                        // returned by /api/contact/rank_ids
  {
    rank : number?,
    ids : string array
  }

  order := "name" | "rank" | "volume" | "lastCall" | "balance"

  syncRequest :=                  // passed to /api/contact/sync
  {
    updated : in_contact array,   // contacts added/modified by client since the last sync.  only the localId
                                  // field is used in each record, the id field is ignored
    deleted : string array,       // ids of contacts deleted by client since the last sync (client localIds)
    replaceAll : boolean,         // if true, replace all the existing contacts at server with the new contacts at client
    isFast     : boolean,         // if true, this is a "fast" sync: only changes since the last sync are applied from the server
    sourceId   : string,          // uniquely identifies this specific client and must be consistent for all calls from
                                  // this client.  may be ""
    max_changes: int?,            // limit the max number of items returned in syncResponse.updated
    anchor   : string?,           // (field incorporated from syncComplete)
    id_map   : (string, int) map? // (field incorporated from syncComplete)
  }

  syncResponse :=                 // returned by /api/contact/sync
  {
    updated : in_contact array,   // contacts added/modified by server since the last sync.  the id field
                                  // will always be populated.  for updated contacts, localId will be populated
                                  // as well.  if localId is not populated, then the client must treat this as
                                  // a new contact and add it. the localId must be reported back to the server
                                  // via /api/contact/sync/complete
    deleted : string array,       // ids of contacts deleted by server since the last sync (as localId)
    more_changes : boolean,       // whether server has more changes to sync
    anchor  : string              // the client's last sync anchor
  }

  syncInitRequest :=              // passed to /api/contact/sync/init
  {
    sourceId : string             // uniquely identifies the client, this must be the same as used in syncRequest
  }

  syncInitResponse :=             // returned from /api/contact/sync/init
  {
    anchor   : string             // the client's last sync anchor (as set in /api/contact/sync or /api/contact/sync/complete)
  }

  syncComplete :=                 // passed to /api/contact/sync/complete
  {
    anchor   : string,            // the client's last sync anchor (returned by /api/contact/sync/init
    sourceId : string,            // uniquely identifies the client, this must be the same as used in syncRequest
    id_map   : (string, int) map  // map of localId to server id, this should contain the ids for all the
                                  // contacts added to the client from a syncResponse
  }
          

API calls:

URL /api/contact/get
Function Returns contacts from user's address book.
CapabilityContact_read
Arguments
order?orderSort order
limit? numberLimit number of contacts returned
query? stringMatch address book query as in application
tag? stringMatch contacts with given tag
id? numberMatch contact with given id
phoneNumber? stringMatch contacts with given phone number
im? stringMatch contacts with given IM handle
email? stringMatch contacts with given email address
Returnscontact array
 
URL /api/contact/tags
Function Gets all contact tags for user, with counts.
CapabilityContact_read
Returns (string, int) map
 
URL /api/contact/update
Function Sets fields on contact in user's address book.
CapabilityContact_write
POST body in_contact
 
URL /api/contact/add
Function Adds a new contact in user's address book.
CapabilityContact_write
POST body in_contact
 
URL /api/contact/delete
Function Deletes a contact in user's address book.
CapabilityContact_write
Arguments
idnumberID of contact to delete
 
URL /api/contact/sync
Function Performs two-way synchronization on user's address book.
CapabilityContact_write
POST body syncRequest
Returns syncResponse
 
URL /api/contact/sync/init
Function Gets the last sync anchor stored on the server. A client that stores its sync anchor locally does not need to call this.
CapabilityContact_write
POST body syncInitRequest
Returns syncInitResponse
 
URL /api/contact/sync/complete
Function Updates the localId to server Id mapping for syncing contacts and saves the last sync anchor for the client. Clients must call this after adding new local contacts while handling a syncResponse
CapabilityContact_write
POST body syncMap
 
URL /api/contact/rank_ids
Function Rank a set of identifiers (phone numbers, IM handles, or email addresses) according to user's address book.
CapabilityContact_rank_ids
Arguments
id stringidentifier to rank (may appear multiple times)
Returns ranked_id array