Account & Profile Management

Explain accout and profile managment


Creating an account

/signUp [POST]
Consumes
JSON in body
  { "passPhrase" : string (required),
    "password" : string (required),
    "email" : string (required),
    "avatar" : data uri schema string,
    "firstName" : string (required),
    "middleName" : string,
    "lastName" : string (required),
    "personalEmail" : string,
    "personalPhone" : string,
    "country" : uuid string (required),
    "gender" : uuid string,
    "employer" : string,
    "jobTitle" : string,
    "businessEmail" : string,
    "businessPhone" : string,
    "mailPassPhrase" : boolean (default false)
  }
  
Returns 200 OK
Empty body

400 Fields mismatch
  { "status" : "registration-failed",
    "data" : {"fields" : [ string ] }
  }
Requires None

Exampje (Node.js)

var request = require("request");

var options = { method: 'POST',
  url: 'https://apibeta.onlyonce.com/v2/signUp',
  headers: 
   { 'content-type': 'application/json'
  body: 
   { passPhrase: '12341234',
     password: '12341234',
     email: '12341234@zdevops.com',
     firstName: 'Een Twee Drie Vier',
     middleName: 'hoedje_van_hoedje_van',
     lastName: 'Papier',
     personalEmail: '1234@hoedjevanpapier.com',
     personalPhone: '+318812341234'
     country: '64a26eb4-7e0d-43e0-a993-1b1535da1d63',
     gender: 'c5e1dc28-f0f8-4f72-9a2a-1ff20ece7eef'
    }
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

Logging on (retrieve JWT-token)

/signIn [POST]
Consumes
JSON in body
  {
    "username" : string (required),
    "password" : string (required)
  }
  
Returns 200 OK
[in header] Authorization -> Bearer eyJhbGci...

401 UNAUTHORIZED
You've given invalid credentials

403 Forbidden
{
  "status": "access-denied"
}
500 ERROR
JSON body missing or mal-formatted
Requires None

Exampje (Node.js)

var request = require("request");

var options = { method: 'POST',
  url: 'https://api.onlyonce.com/v2/signIn',
  headers: { 'content-type': 'application/json' },
  body: { 
    username: 'yourusername@yourmailprovider.com', 
    password: 'your secret password' 
  },
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

Logging out (invalidate JWT-token)

/signOut [GET]
Consumes
nothing
Returns 200 OK
Invalidated JWT-token
Requires "Authorization" header containing JWT-token

Delete Account (and all profiles)

/account [DELETE]
Consumes
Nothing
Returns 200 OK
-- empty body
Requires "Authorization" header containing JWT-token

Getting account information

/account [GET]
Consumes
Nothing
Returns 200 OK
{
    "email" : "me@email.com",
    "accountLevel" : "FREE",
    "createdDate" : "2016-06-12T23:59:59",
    "emailVerified" : true
}
                
Requires "Authorization" header containing JWT-token

Requesting password reset

/password/change [GET]
Consumes
    ?email=me@email.com
  
Email address for password reset
Returns 200 OK
Empty Body
Requires None

Changing password

/account/changePassword [GET]
Consumes
{
  "oldPassword": string (required),
  "newPassword": string (required)
}
            
Returns 200 OK
--empty body--
401
{
    "status": "authentication-failed"
}
                
Requires "Authorization" header containing JWT-token

Getting list of profiles

/profiles [GET]
Consumes
As parameters
  • ooId : Only Once ID (or part of)
  • name : Profile name (or part of)/li>
  • type : PERSONAL or ORGANIZATION
  • scope : MINE, BOOKMARKS, CONNETIONS, FLEX_WORKERS or REGULAR_WORKERS
  • profileId : The profileID whose bookmarks or connections you want to see. Required if scope is not null or MINE
  • tags : Array of tags to filter on
  • categories : Used for filtering FLEX_WORKERS or REGULAR_WORKERS
  • sortField : fieldName used for sorting
  • sortDirection : asc or desc
Returns
(paginated respsonse)
200 OK
[
  {
      "id": string uuid (notnull),
      "onlyonceId": int (notnull),
      "name": string,
      "avatarId": string uuid,
      "type": "PERSONAL" or "ORGANIZATION" (notnull),
      "createdDate": "yyyy-MM-ddThh:mm:ss.ms" ("2016-06-09T04:10:16.787"),
      "publicCardId": string uuid (notnull),
      "viewsCount": int (notnull),
      "incomingSharesCount": int (notnull),
      "outgoingSharesCount": int (notnull)
      "connectedDate": "2016-07-20T18:39:01.706" (notnull if scope CONNECTIONS),
      "lastModifyDate": "2016-07-20T18:39:01.706" (notnull if scope CONNECTIONS),
      "flexWorkerInfo": { not null if scope FLEX_WORKERS or REGULAR_WORKERS
          "categories": array of strings with categories of job,
          "availableFromDate": "2016-07-20T18:39:01.706" (notnull)
      },
      "bookmarked": boolean,
      "connected": boolean,
      //tags is not null if scope = MINE or profileId passed
      //if scope mine = all owned tags will be added
      "tags": [{ 
          "ownerId": string uuid (notnull),
          "targetId": string uuid (notnull),
          "tag": string (notnull),
      }]
  }
]
                
Requires "Authorization" header containing JWT-token

Example (Node.js)

var request = require("request");

var options = { method: 'GET',
  url: 'https://api.onlyonce.com/v2/profiles',
  qs: { scope: 'MINE' },
  headers: 
   { 'content-type': 'application/json',
     authorization: 'Bearer eyJhbGciOiJIUzUxMiJ9...' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

>>> Yields:

{
  "last": true,
  "total": 1,
  "content": [
    {
      "id": "604c8f4d-4f2a-40a8-b918-0e945a0ce11e",
      "onlyonceId": 1446,
      "name": "Alice Apideveloper",
      "viewsCount": 0,
      "incomingSharesCount": 0,
      "outgoingSharesCount": 0,
      "type": "PERSONAL",
      "createdDate": "2016-09-04T20:38:50.605",
      "publicCardId": "35a21c76-018d-470a-ba0f-c8cdd6054267",
      "tags": []
    }
  ]
}

Enabling access required endpoints for passed profile id

/profiles/{id}/access [POST]
Consumes
"Secret-Key" header with passPhrase
Returns
(paginated respsonse)
200 OK
--empty body--

401
{
  "status" : "wrong-secret-key"
}
            
Requires "Authorization" header containing JWT-token

The access-enablement expires. Once this expires every endpoint requiring it will throw a 401 with the following body:

{
      "status": "wrong-secret-key",
      "data": "Secret key for profile 291d2906-2509-4112-ba09-40af62f00dc4 expired"
}


Change secret key for passed profile id

/profiles/{id}/chagePassPhrase [POST]
Consumes
{
  "passPhrase" : string required,
  "newPassPhrase" : string required
}
                
Returns
(paginated respsonse)
200 OK
--empty body--

401
{
  "status" : "wrong-secret-key"
}
Requires "Authorization" header containing JWT-token

Getting profile information

/profiles/{id} [GET]
Consumes
As parameters
  • currentProfileId : The profileID whose bookmarks or connections you want to see. Required if scope is not null or MINE
Returns
200 OK
{
      "id": string uuid (notnull),
      "onlyonceId": int (notnull),
      "name": string,
      "avatarId": string uuid,
      "type": "PERSONAL" or "ORGANIZATION" (notnull),
      "createdDate": "yyyy-MM-ddThh:mm:ss.ms" ("2016-06-09T04:10:16.787"),
      "publicCardId": string uuid (notnull),
      "viewsCount": int (notnull),
      "incomingSharesCount": int (notnull),
      "outgoingSharesCount": int (notnull)
      "connectedDate": "2016-07-20T18:39:01.706" (notnull if scope CONNECTIONS),
      "lastModifyDate": "2016-07-20T18:39:01.706" (notnull if scope CONNECTIONS),
      "flexWorkerInfo": { not null if scope FLEX_WORKERS or REGULAR_WORKERS
          "categories": array of strings with categories of job,
          "availableFromDate": "2016-07-20T18:39:01.706" (notnull)
      },
      "bookmarked": boolean,
      "connected": boolean,
      //tags is not null if scope = MINE or profileId passed
      //if scope mine = all owned tags will be added
      "tags": [{ 
          "ownerId": string uuid (notnull),
          "targetId": string uuid (notnull),
          "tag": string (notnull),
      }]
}
                
Requires "Authorization" header containing JWT-token

Creating an Organizational Profile

/profiles [POST]
Consumes
{
    "passPhrase": string (required),
    "email": string (required)

    "tradeName": string (required, uniq),
    "legalEntityType": "a2fadfd9-db52-45f9-b853-5f0f0e2fc36f",
    "country": "1851877e-7a48-4949-87ee-6ba5ee04c889",

    "mailPassPhrase": boolean (default false)
}
Returns
(paginated respsonse)
200 OK
-- empty body --
Secret-Key in header (??)
Requires "Authorization" header containing JWT-token

Deleting an Organizational Profile

/profiles/{id}[DELETE]
Consumes
Nothing
Returns
200 OK
--empty body--

401
{
  "status" : "wrong-auth?"
}
            
Requires "Authorization" header containing JWT-token

Adding another profile to bookmarks

/profiles/{id}/bookmarks [POST]
Consumes
{
    "id": string uuid(required)
}
Returns 200 OK
-- empty body --
Requires "Authorization" header containing JWT-token

Deleting a profile from bookmarks

/profiles/{id}/bookmarks/{profileId} [DELETE]
Consumes Nothing
Returns 200 OK
-- empty body --
Requires "Authorization" header containing JWT-token

Adding a tag to a profile

/profiles/tags [POST]
Consumes
{
    "ownerId": string uuid (required),
    "targetId": string uuid (required),
    "tag" : string (rerquired)    
}
Returns
200 OK
-- empty body --
Requires "Authorization" header containing JWT-token

Removing a tag from a profile

/profiles/tags [DELETE]
Consumes
{
    "ownerId": string uuid (required),
    "targetId": string uuid (required),
    "tag" : string (rerquired)    
}
Returns
200 OK
-- empty body --
Requires "Authorization" header containing JWT-token

Add a note to a profile

/profiles/{id}/notes [POST]
Consumes
{
    "type": string (notnull),
    "text" : string (notnull),
    "ownerId": string uuid (notnull)
}
Returns
200 OK
string uuid
Requires "Authorization" header containing JWT-token

Get notes of profile

/profiles/{id}/notes [GET]
Consumes
Parameters
ownerId (required)
Returns
200 OK
[
    {
      "id": string uuid (notnull),
      "type": string (notnull),
      "text": string (notnull),
      "ownerId":  string uuid (notnull)
    }
]
Requires "Authorization" header containing JWT-token

Update notes of profile

/profiles/{id}/notes [PUT]
Consumes
{
    "id" : uuid string (notnull),
    "type": string (notnull),
    "text" : string (notnull),
    "ownerId": string uuid (notnull)
}
Returns
200 OK
--empty body--
Requires "Authorization" header containing JWT-token

Delete a note

/profiles/{id}/notes/{noteId} [DELETE]
Consumes Nothing
Returns
200 OK
-- empty body --
Requires "Authorization" header containing JWT-token

Getting activity list

/activities [GET]
Consumes
Parameters
  • scope : NETWORK_UPDATES, PDS_MUTATIONS, PROFILE or ACCOUNT
  • profileId : Required if scope empty or scope != ACCOUNT
Returns
Paginated respsonse
200 OK
[
    {
      "id": uuid string,
      "accountId": uuid string,
      "occurred": "yyyy-MM-ddThh:mm:ss.ms" ("2016-06-09T04:10:16.787"),
      "entityName": string,
      "actionName": string,
      "remoteIp": string,
      "activityType": string "ACCOUNT",
      "arguments": {
        "browserType": string,
        "browserVersion": string,
        "deviceType": string,
        "deviceOS": string
      }
    },
    {
      "id": uuid string,
      "accountId": uuid string,
      "occurred": "yyyy-MM-ddThh:mm:ss.ms" ("2016-06-09T04:10:16.787"),
      "entityName": string",
      "actionName": string,
      "sourceId": uuid string,
      "targetId": uuid string,
      "subject": uuid string,
      "activityType": string "NETWORK_UPDATES" or "PDS_MUTATIONS",
      "arguments": {
        "dataSetName": String,
        "fieldsAdded": [string]
      }
    },
    {???}
]
                
Requires "Authorization" header containing JWT-token

Getting profile settings

/profiles/{id}/settings [GET]
Consumes Nothing
Returns 200 OK
{
  "searchableByName": boolean,
  "broadcastDataChanges": boolean,
  "avatarVisibility": string ("NOBODY", "CONNECTED_USERS" or "ALL"),
  "visibleExternally": boolean,
  "emailNotificationTypes": array of [
    "NEW_MESSAGE",
    "WEEKLY_SUMMARY",
    "OO_NEWSLETTER",
    "PRODUCT_UPDATES",
    "PRODUCT_USER_SURVEYS"
  ],
  "communicationChannelsOrder": [
    "communication_landline3_field",
    "communication_landline2_field",
    "communication_landline1_field",
    "communication_mobtel1_field",
    "communication_mobtel2_field",
    "communication_email1_field",
    "communication_email2_field",
    "communication_email3_field",
    "communication_email4_field",
    "communication_hangout_field",
    "communication_facetime_field",
    "communication_skype_field"
  ]
}
}
                
Requires "Authorization" header containing JWT-token

Changing profile settings

/profiles/{id}/settings [PUT]
Consumes
{
  "searchableByName": boolean,
  "broadcastDataChanges": boolean,
  "avatarVisibility": string ("NOBODY", "CONNECTED_USERS" or "ALL"),
  "visibleExternally": boolean,
  "emailNotificationTypes": array of [
    "NEW_MESSAGE",
    "WEEKLY_SUMMARY",
    "OO_NEWSLETTER",
    "PRODUCT_UPDATES",
    "PRODUCT_USER_SURVEYS"
  ],
  "communicationChannelsOrder": [
    "communication_landline3_field",
    "communication_landline2_field",
    "communication_landline1_field",
    "communication_mobtel1_field",
    "communication_mobtel2_field",
    "communication_email1_field",
    "communication_email2_field",
    "communication_email3_field",
    "communication_email4_field",
    "communication_hangout_field",
    "communication_facetime_field",
    "communication_skype_field"
  ]
}
}
                
Returns 200 OK
--empty body--
Requires "Authorization" header containing JWT-token

Listing all organisations

/companies [GET]
Consumes
Params
employerName (required)
Returns 200 OK
[
  {
    "onlyOnceId": number (notnull),
    "name": string (notnull)
  }
]
                
Requires None

Datastore Management

Explain datastore managment


Retrieving Datastore

/profiles/{id}/dataStore [GET]
Consumes Nothing
Returns
200 OK
??????
Requires "Authorization" header containing JWT-token
Access Required

Add fields to dataStore. Used for adding groups and wrappers.

/profiles/{id}/dataStore/addFields [POST]
Consumes
[
    {
      "definitionName": string (required),
      "value": string (required),
      "parentValueId": string,
    }
]
Returns
200 OK
[
    {
      "definitionName": string (required),
      "value": string (required),
      "parentValueId": string,
    }
]
Requires "Authorization" header containing JWT-token
Access Required

Save or update datastore fields

/profiles/{id}/dataStore/saveFields [POST]
Consumes
[  
    {  
       "definitionName": string (notnull),
       "value": string or object (see next) (not null),
       "parentValueId": uuid string
    },
    {  
       "definitionName": string (notnull),
       "value": {  
         "id": uuid string from dictionary,
       },
       "parentValueId": uuid string
    }
]
Returns
200 OK
see /profiles/{id}/dataStore
Requires "Authorization" header containing JWT-token
Access Required

Delete a field from datastore

/profiles/{id}/dataStore/fields/{fieldID} [DELETE]
Consumes Nothing
Returns
200 OK
--empty body--
Requires "Authorization" header containing JWT-token

Card Management

Explain datastore managment


Getting list of cards

/profiles/{id}/cards [GET]
Consumes
Params
scope (required)
MINE - cards owned by the passed profile
ACCEPTED - accepted cards received from other profiles
Returns 200 OK
[
    {
      "id": string uuid (notnull),
      "name": string(notnull),
      "ownerId": string uuid (notnull),
      "dataSetType": string "PUBLIC_CARD" or "SHAREABLE_CARD" (notnull),
      "predefined": boolean (notnull),
      "predefinedType": string (notnull if "predefined" = true),
      "pendingRequestsCount": number (notnull if scope = MINE),
      "acceptedRequestsCount": number (notnull if scope = MINE)
    }
]
                
Requires None

Getting content of specific card

/profiles/{id}/cards/{cardId} [GET]
Consumes Nothing
Returns 200 OK
???
                
Requires "Authorization" header containing JWT-token
Access Required

Creating a new card

/profiles/{id}/cards [POST]
Consumes
{
  "name": string (required, should not be eq with existed),
  "fields":[ array of fieldValueIds from dataStore]
}
Returns 200 OK

{
    "id": string uuid (notnull),
}            
Requires "Authorization" header containing JWT-token
Access Required

Cloning a card

/profiles/{id}/cards{cardId}/clone [POST]
Consumes
Nothing
Returns 200 OK
{
    "id": string uuid (notnull),
}            
Requires "Authorization" header containing JWT-token
Access Required

Updating a card

/profiles/{id}/cards{cardId} [PUT]
Consumes
{
  "name": string (required, should not be eq with existed),
  "fields":[ array of fieldValueIds from dataStore]
}
Returns 200 OK
--empty body--
Requires "Authorization" header containing JWT-token
Access Required

Deleting a card

/profiles/{id}/cards{cardId} [DELETE]
Consumes
Nothing
Returns 200 OK
--empty body--
Requires "Authorization" header containing JWT-token

Network Management

Explain datastore managment


Listing share requests

/profiles/{id}/requests [GET]
Consumes
Parameters
  • type : "INCOMING" or "OUTGOING"
  • tagetId : second side of request, depends on type
  • statuses : "PENDING", "ACCEPTED", "DECLINED" or "REVOKED"
  • cardId : Filter by cardId
  • sortField : Fieldname to sort
  • sortDirection : "asc" or "desc"
Returns
Paginated Response
200 OK
[
    {
      "id": string uuid (notnull),
      "sender": object (notnull), see '/profiles' response
      "cardId": string uuid (notnull),
      "recipient": object (notnull), see '/profiles' response
      "status": "PENDING",
      "connected": boolean (notnull),
      "requested": date (notnull),
      "completed": date
    }
]
Requires "Authorization" header containing JWT-token

Sending share request to other profile

This endpoint is used to share a card OR to request a card.

Share a card: reversed = False, Request a card: reversed = True

/requests [POST]
Consumes
Parameters
[
  "cardId": string uuid (required),
  "recipient": { 
    "id": string uuid (required)
  },
  "sender": {
      "id": string uuid (required)
  },
  "reversed": boolean (default = false, true if it's card request)
]
             
Returns
200 OK
[
  "id": string uuid (notnull),
  "sender": object (notnull), see '/profiles' response
  "cardId": string uuid (notnull),
  "recipient": object (notnull), see '/profiles' response
  "status": "PENDING",
  "connected": boolean (notnull),
  "requested": date (notnull),
  "completed": date
]

401
{
    "status": "wrong-request-status"
}

401
{
    "status": "encryption-error"
}
Requires "Authorization" header containing JWT-token
Access Required

Bulk operations on requests

/requests{action} [POST]
Consumes
Path variables + JSON Body
  • accept
  • decline
  • revoke
{
    "ids" : [string uuid]
}
Returns
Paginated Response
200 OK
--empty body--
401
{
    "status": "wrong-request-status"
}

401
{
    "status": "wrong-request-owner"
}

Requires "Authorization" header containing JWT-token

Various Support Endpoints

Explain them


Find Predefined Values for fixed fields

/dictionaries [GET]
Consumes
Params
fieldDefinitionName (required)
Returns 200 OK
[
  {
    "id": uuid string (notnull),
    "order": int (notnull),
    "value": string (notnull)
  }
]
                
Requires None

Example (Node.js)

var request = require("request");

var options = { method: 'GET',
  url: 'https://apibeta.onlyonce.com/v2/dictionaries',
  qs: { fieldDefinitionName: 'country_field' },
  headers: { 'content-type': 'application/json' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

>> Returns

[
  {
    "id": "88e43225-4127-4092-bf6a-3b4e0a67f8bc",
    "order": 0,
    "value": "Afghanistan"
  },
  {
    "id": "4c1ab58f-354c-490c-a9cb-8b9fd23adf1c",
    "order": 1,
    "value": "Albania"
  },
  ...

Get consolidated view of network

/consolidated [GET]
Consumes
Params
profileId (required)
fieldNames (multiples)
Returns
200 OK
Set of requested data for network
Requires "Authorization" header containing JWT-token
Access Required

Possible 'fieldNames'

For a full list of fieldNames see /fieldnames

Example (Node.js)

var request = require("request");

var options = { method: 'GET',
  url: 'https://api.onlyonce.com/v2/consolidated',
  qs: 
   { profileId: '291d2906-2509-4112-ba09-40af62f00dc4',
     fieldNames: [ 'first_name_field', 'communication_email1_field' ] },
  headers: 
   { 'content-type': 'application/json',
     authorization: 'Bearer eyJhbGciOiJIUzUxMiJ9...' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

>>> Yields:

{
  "last": true,
  "total": 25,
  "content": [
    {
      "d1cb10a4-4f16-481a-b81a-ff209c7a9682": {
        "first_name_field": "atester11",
        "communication_email1_field": "atester11@kaalverink.net"
      }
    },
    {
      "48e172a8-582a-4e52-a0ad-efb8d0b49074": {
        "first_name_field": "Roel",
        "communication_email1_field": "roel.peels@onlyonce.com"
      }
    },
    {
      "08ae8f60-0e44-49ab-a2d7-75bde2957d33": {
        "first_name_field": "M",
        "communication_email1_field": null
      }
    },
    {
      "4e9ca135-5af3-4c71-b70c-cf136cbe203a": {
        "first_name_field": "Henri",
        "communication_email1_field": null
      }
    },
    {
      "a98c69be-fed6-4915-8854-4ec8bcdac503": {
        "first_name_field": null,
        "communication_email1_field": null
      }
    }, 
  ]
}

Get status of API

/heartbeat [GET]
Consumes Nothing
Returns 200 OK
{
  "nodeName": "onlyonce-api-web-e058922c948f4c47a426f49fbbfabd54",
  "since": "2016-07-20T19:35:40.3"
}
                
Requires None

Exampje (Node.js)

var request = require("request");

var options = { method: 'GET',
  url: 'https://api.onlyonce.com/v2/heartbeat',
  headers: { 'content-type': 'application/json' },
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});


>>> Yields:

{
  "nodeName": "onlyonce-api-web-f2705011771b4027b72bfd34b29b2a1f",
  "since": "2016-09-08T14:39:59.978"
}

# If API is down 

{
  "status": 500, 
  "reason":"API DOWN"
}



Get metainformation on a file

/files/{fileMetadataId}/info [GET]
Consumes Nothing
Returns
200 OK
{
  "id": uuid string (notnull),
  "name": sring (notnull),
  "size": number (notnull),
  "description": string
}

Requires "Authorization" header containing JWT-token

Download a file

/profiles/{profileId}/files/{fileMetadataId}/download[GET]
Consumes Nothing
Returns
200 OK
byte[]
Requires "Authorization" header containing JWT-token
Access Required

Upload a file

/profiles/{profileId}/files[POST]
Consumes
Content-Disposition: form-data; name="file"
Content-Type: ---contentType of file
---file

Content-Disposition: form-data; name="metadata"
Content-Type: "application/json"
{
  "fieldDefinitionName": string (notnull if dataStore field)
  "parentFieldValueId": string,
  "avatar": boolean (notnull)
  "description": string
}
Returns
200 OK
see /files/{fileMetadataId}/info
Requires "Authorization" header containing JWT-token
Access Required (when uploading to datastore)

Delete a file

/profiles/{id}/files/{fileMetadataId} [DELETE]
Consumes Nothing
Returns 200 OK
-- empty body --
Requires "Authorization" header containing JWT-token

© 2016-2017, All rights reserved, Only Once (version 0.90.22, 2017-05-22).