Invite

In this scenario, we'll invite two people to a project and one of them will accept the invitation. First step is to create a project:

Response: HTTP 200, application/json (Hide)
POST /projects

Payload:

1
2
3
{
    "name": "New project"
}

Response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{
    "single": {
        "id": 1,
        "class": "Project",
        "url_path": "\/projects\/1",
        "name": "New project",
        "completed_on": null,
        "completed_by_id": null,
        "is_completed": false,
        "members": [
            1
        ],
        "category_id": 0,
        "label_id": 0,
        "is_trashed": false,
        "trashed_on": null,
        "trashed_by_id": 0,
        "created_on": 1430164633,
        "created_by_id": 1,
        "updated_on": 1430164633,
        "updated_by_id": 1,
        "body": null,
        "body_formatted": "",
        "company_id": 1,
        "leader_id": 0,
        "currency_id": 2,
        "template_id": 0,
        "based_on_type": null,
        "based_on_id": null,
        "email": "notifications+m2p-8D4Ijb0@mail.manageprojects.com",
        "is_tracking_enabled": true,
        "is_client_reporting_enabled": false,
        "budget": null,
        "count_tasks": 0,
        "count_discussions": 0,
        "count_files": 0,
        "count_notes": 0
    },
    "category": null,
    "hourly_rates": {
        "1": 100
    },
    "label_ids": [],
    "task_lists": null
}

Next, we'll send two invitations:

Response: HTTP 200, application/json (Hide)
POST /users/invite

Payload:

1
2
3
4
5
6
7
8
9
10
{
    "email_addresses": [
        "first@activecollab.com",
        "Peter Smith <peter@activecollab.com>"
    ],
    "role": "Member",
    "project_ids": [
        1
    ]
}

Response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
[
    {
        "id": 2,
        "class": "Member",
        "url_path": "\/users\/2",
        "is_archived": false,
        "is_trashed": false,
        "trashed_on": null,
        "trashed_by_id": 0,
        "created_on": 1430164633,
        "created_by_id": 1,
        "updated_on": 1430164633,
        "updated_by_id": 1,
        "language_id": 0,
        "first_name": "First",
        "last_name": null,
        "display_name": "first",
        "short_display_name": "first",
        "email": "first@activecollab.com",
        "additional_email_addresses": [],
        "is_pending_activation": true,
        "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=2&size=--SIZE--&timestamp=1430164633",
        "custom_permissions": [],
        "company_id": 0,
        "title": null,
        "phone": null,
        "im_type": null,
        "im_handle": null,
        "note": null
    },
    {
        "id": 3,
        "class": "Member",
        "url_path": "\/users\/3",
        "is_archived": false,
        "is_trashed": false,
        "trashed_on": null,
        "trashed_by_id": 0,
        "created_on": 1430164633,
        "created_by_id": 1,
        "updated_on": 1430164633,
        "updated_by_id": 1,
        "language_id": 0,
        "first_name": "Peter",
        "last_name": "Smith",
        "display_name": "Peter Smith",
        "short_display_name": "Peter S.",
        "email": "peter@activecollab.com",
        "additional_email_addresses": [],
        "is_pending_activation": true,
        "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=3&size=--SIZE--&timestamp=1430164633",
        "custom_permissions": [],
        "company_id": 0,
        "title": null,
        "phone": null,
        "im_type": null,
        "im_handle": null,
        "note": null
    }
]

Note that email_addresses is an array of addresses. It can also be a RFC822 compatible string:

Response: HTTP 200, application/json (Hide)
POST /users/invite

Payload:

1
2
3
4
{
    "email_addresses": "santino@activecollab.com, Vito Corleone <vito@activecollab.com>",
    "role": "Member"
}

Response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
[
    {
        "id": 4,
        "class": "Member",
        "url_path": "\/users\/4",
        "is_archived": false,
        "is_trashed": false,
        "trashed_on": null,
        "trashed_by_id": 0,
        "created_on": 1430164633,
        "created_by_id": 1,
        "updated_on": 1430164633,
        "updated_by_id": 1,
        "language_id": 0,
        "first_name": "Santino",
        "last_name": null,
        "display_name": "santino",
        "short_display_name": "santino",
        "email": "santino@activecollab.com",
        "additional_email_addresses": [],
        "is_pending_activation": true,
        "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=4&size=--SIZE--&timestamp=1430164633",
        "custom_permissions": [],
        "company_id": 0,
        "title": null,
        "phone": null,
        "im_type": null,
        "im_handle": null,
        "note": null
    },
    {
        "id": 5,
        "class": "Member",
        "url_path": "\/users\/5",
        "is_archived": false,
        "is_trashed": false,
        "trashed_on": null,
        "trashed_by_id": 0,
        "created_on": 1430164633,
        "created_by_id": 1,
        "updated_on": 1430164633,
        "updated_by_id": 1,
        "language_id": 0,
        "first_name": "Vito",
        "last_name": "Corleone",
        "display_name": "Vito Corleone",
        "short_display_name": "Vito C.",
        "email": "vito@activecollab.com",
        "additional_email_addresses": [],
        "is_pending_activation": true,
        "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=5&size=--SIZE--&timestamp=1430164633",
        "custom_permissions": [],
        "company_id": 0,
        "title": null,
        "phone": null,
        "im_type": null,
        "im_handle": null,
        "note": null
    }
]

Now that we demonstrated how email_addresses can be used, lets move these accounts to the trash:

Response: HTTP 200, application/json (Hide)
DELETE /users/4

Response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
    "single": {
        "id": 4,
        "class": "Member",
        "url_path": "\/users\/4",
        "is_archived": false,
        "is_trashed": true,
        "trashed_on": 1430164633,
        "trashed_by_id": 1,
        "created_on": 1430164633,
        "created_by_id": 1,
        "updated_on": 1430164633,
        "updated_by_id": 1,
        "language_id": 0,
        "first_name": "Santino",
        "last_name": null,
        "display_name": "santino",
        "short_display_name": "santino",
        "email": "santino@activecollab.com",
        "additional_email_addresses": [],
        "is_pending_activation": false,
        "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=4&size=--SIZE--&timestamp=1430164633",
        "custom_permissions": [],
        "company_id": 0,
        "title": null,
        "phone": null,
        "im_type": null,
        "im_handle": null,
        "note": null
    }
}
Response: HTTP 200, application/json (Hide)
DELETE /users/5

Response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
    "single": {
        "id": 5,
        "class": "Member",
        "url_path": "\/users\/5",
        "is_archived": false,
        "is_trashed": true,
        "trashed_on": 1430164634,
        "trashed_by_id": 1,
        "created_on": 1430164633,
        "created_by_id": 1,
        "updated_on": 1430164634,
        "updated_by_id": 1,
        "language_id": 0,
        "first_name": "Vito",
        "last_name": "Corleone",
        "display_name": "Vito Corleone",
        "short_display_name": "Vito C.",
        "email": "vito@activecollab.com",
        "additional_email_addresses": [],
        "is_pending_activation": false,
        "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=5&size=--SIZE--&timestamp=1430164634",
        "custom_permissions": [],
        "company_id": 0,
        "title": null,
        "phone": null,
        "im_type": null,
        "im_handle": null,
        "note": null
    }
}

Back to the original group of invitees. Lets check that they are added to the project:

Response: HTTP 200, application/json (Hide)
GET /projects/1

Response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
{
    "single": {
        "id": 1,
        "class": "Project",
        "url_path": "\/projects\/1",
        "name": "New project",
        "completed_on": null,
        "completed_by_id": null,
        "is_completed": false,
        "members": [
            1,
            2,
            3
        ],
        "category_id": 0,
        "label_id": 0,
        "is_trashed": false,
        "trashed_on": null,
        "trashed_by_id": 0,
        "created_on": 1430164633,
        "created_by_id": 1,
        "updated_on": 1430164633,
        "updated_by_id": 1,
        "body": null,
        "body_formatted": "",
        "company_id": 1,
        "leader_id": 0,
        "currency_id": 2,
        "template_id": 0,
        "based_on_type": null,
        "based_on_id": null,
        "email": "notifications+m2p-8D4Ijb0@mail.manageprojects.com",
        "is_tracking_enabled": true,
        "is_client_reporting_enabled": false,
        "budget": null,
        "count_tasks": 0,
        "count_discussions": 0,
        "count_files": 0,
        "count_notes": 0
    },
    "category": null,
    "hourly_rates": {
        "1": 100
    },
    "label_ids": [],
    "task_lists": null
}

Since /users/invite does not return actual invitation objects, we can't check whether accept invitation page works, unless we resend the invitation:

Response: HTTP 200, application/json (Hide)
PUT /users/2/resend-invitation

Response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
    "single": {
        "id": 1,
        "class": "UserInvitation",
        "url_path": "#",
        "created_on": 1430164633,
        "created_by_id": 1,
        "updated_on": 1430164633,
        "code": "JFXupA0wtObxmpM43hqB"
    },
    "invited_to": {
        "id": 1,
        "class": "Project",
        "name": "New project"
    }
}

Now, lets check accept invitation page:

Response: HTTP 200, application/json (Hide)
GET /accept-invitation

Query Parameters:

1
2
3
4
{
    "user_id": 2,
    "code": "$invitation_code"
}

Response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
    "status": "acceptable",
    "user": {
        "id": 2,
        "email": "first@activecollab.com",
        "first_name": null,
        "last_name": null
    },
    "invited_by": {
        "id": 1,
        "full_name": "ilija.studen",
        "first_name": null,
        "last_name": null
    },
    "invited_to": {
        "id": 1,
        "class": "Project",
        "name": "New project"
    }
}

This response tells us a couple of things: who was invited, where, by whome and what is the status of the invitation. There are two possible statuses of an invitation:

  1. acceptable - All green, show the form and let user accept the invitation
  2. already_accepted - User already logged in, so they are already familiar with the system.

To accept an invitation, we need to send POST request to the /accept-invitation command. Four parameters are accepted:

  1. first_name, required
  2. last_name, required
  3. password, required
  4. language_id, optional (default language will be used when this parameter is not provided)
  5. uploaded_avatar_code, optional (file code returned by /upload-files command that was used to upload a user avatar)

Here we go, lets accept the invitation. On successful invitation, ActiveCollab will automatically log the user in:

Response: HTTP 200, application/json (Hide)
POST /upload-files

Files:

1
2
3
4
5
6
[
    [
        "ac.png",
        "image\/png"
    ]
]

Response:

1
2
3
4
5
6
7
8
9
[
    {
        "code": "GWd9hPxqlYkFHSOkw6gQmQeNfDoi7fLC2Oz0sXpD",
        "name": "ac.png",
        "mime_type": "image\/png",
        "size": 1927,
        "thumbnail_url": "http:\/\/feather.dev\/proxy.php?proxy=forward_thumbnail&module=system&v=current&b=DEV&context=upload&name=2015-04%2Ffj2alOdpzd6LBwMAiHA5uUHiNPr8trJzAAzMdC3C&original_file_name=ac.png&width=--WIDTH--&height=--HEIGHT--&ver=1927&scale=--SCALE--"
    }
]
Response: HTTP 200, application/json (Hide)
POST /accept-invitation

Query Parameters:

1
2
3
4
{
    "user_id": 2,
    "code": "$invitation_code"
}

Payload:

1
2
3
4
5
6
{
    "first_name": "John",
    "last_name": "Doe",
    "password": "1234567890",
    "uploaded_avatar_code": "GWd9hPxqlYkFHSOkw6gQmQeNfDoi7fLC2Oz0sXpD"
}

Response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
{
    "logged_user_id": 2,
    "settings": {
        "login_policy": {
            "username_format": "email",
            "remember_extends_session": true,
            "password_change_enabled": true,
            "password_recovery_enabled": true,
            "external_login_url": null,
            "external_logout_url": null,
            "external_change_password_url": null,
            "external_update_profile_url": null
        },
        "password_policy": {
            "min_length": 0,
            "require_numbers": false,
            "require_mixed_case": false,
            "require_symbols": false
        },
        "homepage": null,
        "wallpaper": "wallpaper.jpg",
        "format_date": "%b %e. %Y",
        "format_time": "%I:%M %p",
        "time_first_week_day": 0,
        "timezone": "UTC",
        "gmt_offset": 0,
        "display_mode_projects": "grid",
        "display_mode_project_files": "grid",
        "display_mode_project_time": "list",
        "display_mode_invoices": "grid",
        "display_mode_estimates": "grid",
        "group_mode_people": "first_letter",
        "sort_mode_projects": "activity",
        "sort_mode_project_notes": "recently_updated",
        "default_project_label_id": null,
        "my_work_projects_order": [],
        "my_work_collapsed_sections": [],
        "show_visual_editor_toolbar": false
    },
    "users": [
        {
            "id": 1,
            "class": "Owner",
            "url_path": "\/users\/1",
            "is_archived": false,
            "is_trashed": false,
            "trashed_on": null,
            "trashed_by_id": 0,
            "created_on": 1430164630,
            "created_by_id": 1,
            "updated_on": 1430164630,
            "updated_by_id": 1,
            "language_id": 0,
            "first_name": "Ilija.studen",
            "last_name": null,
            "display_name": "ilija.studen",
            "short_display_name": "ilija.studen",
            "email": "ilija.studen@activecollab.com",
            "additional_email_addresses": [],
            "is_pending_activation": false,
            "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=1&size=--SIZE--&timestamp=1430164630",
            "custom_permissions": [],
            "company_id": 1,
            "title": null,
            "phone": null,
            "im_type": null,
            "im_handle": null,
            "note": null
        },
        {
            "id": 4,
            "class": "Member",
            "url_path": "\/users\/4",
            "is_archived": false,
            "is_trashed": true,
            "trashed_on": 1430164633,
            "trashed_by_id": 1,
            "created_on": 1430164633,
            "created_by_id": 1,
            "updated_on": 1430164633,
            "updated_by_id": 1,
            "language_id": 0,
            "first_name": "Santino",
            "last_name": null,
            "display_name": "santino",
            "short_display_name": "santino",
            "email": "santino@activecollab.com",
            "additional_email_addresses": [],
            "is_pending_activation": false,
            "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=4&size=--SIZE--&timestamp=1430164633",
            "custom_permissions": [],
            "company_id": 0,
            "title": null,
            "phone": null,
            "im_type": null,
            "im_handle": null,
            "note": null
        },
        {
            "id": 2,
            "class": "Member",
            "url_path": "\/users\/2",
            "is_archived": false,
            "is_trashed": false,
            "trashed_on": null,
            "trashed_by_id": 0,
            "created_on": 1430164633,
            "created_by_id": 1,
            "updated_on": 1430164634,
            "updated_by_id": 1,
            "language_id": 0,
            "first_name": "John",
            "last_name": "Doe",
            "display_name": "John Doe",
            "short_display_name": "John D.",
            "email": "first@activecollab.com",
            "additional_email_addresses": [],
            "is_pending_activation": false,
            "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=2&size=--SIZE--&timestamp=1430164634",
            "custom_permissions": [],
            "company_id": 0,
            "title": null,
            "phone": null,
            "im_type": null,
            "im_handle": null,
            "note": null
        },
        {
            "id": 3,
            "class": "Member",
            "url_path": "\/users\/3",
            "is_archived": false,
            "is_trashed": false,
            "trashed_on": null,
            "trashed_by_id": 0,
            "created_on": 1430164633,
            "created_by_id": 1,
            "updated_on": 1430164633,
            "updated_by_id": 1,
            "language_id": 0,
            "first_name": "Peter",
            "last_name": "Smith",
            "display_name": "Peter Smith",
            "short_display_name": "Peter S.",
            "email": "peter@activecollab.com",
            "additional_email_addresses": [],
            "is_pending_activation": true,
            "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=3&size=--SIZE--&timestamp=1430164633",
            "custom_permissions": [],
            "company_id": 0,
            "title": null,
            "phone": null,
            "im_type": null,
            "im_handle": null,
            "note": null
        },
        {
            "id": 5,
            "class": "Member",
            "url_path": "\/users\/5",
            "is_archived": false,
            "is_trashed": true,
            "trashed_on": 1430164634,
            "trashed_by_id": 1,
            "created_on": 1430164633,
            "created_by_id": 1,
            "updated_on": 1430164634,
            "updated_by_id": 1,
            "language_id": 0,
            "first_name": "Vito",
            "last_name": "Corleone",
            "display_name": "Vito Corleone",
            "short_display_name": "Vito C.",
            "email": "vito@activecollab.com",
            "additional_email_addresses": [],
            "is_pending_activation": false,
            "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=5&size=--SIZE--&timestamp=1430164634",
            "custom_permissions": [],
            "company_id": 0,
            "title": null,
            "phone": null,
            "im_type": null,
            "im_handle": null,
            "note": null
        }
    ],
    "companies": [
        {
            "id": 1,
            "class": "Company",
            "url_path": "\/companies\/1",
            "name": "Owner Company",
            "members": [
                1
            ],
            "is_trashed": false,
            "trashed_on": null,
            "trashed_by_id": 0,
            "is_archived": false,
            "created_on": 1430164630,
            "created_by_id": 1,
            "updated_on": 1430164630,
            "updated_by_id": 1,
            "address": null,
            "phone": null,
            "homepage_url": null,
            "tax_id": null,
            "currency_id": null,
            "is_owner": true,
            "has_note": false
        }
    ],
    "projects_total": 1,
    "projects": [
        {
            "id": 1,
            "class": "Project",
            "url_path": "\/projects\/1",
            "name": "New project",
            "completed_on": null,
            "completed_by_id": null,
            "is_completed": false,
            "members": [
                1,
                2,
                3
            ],
            "category_id": 0,
            "label_id": 0,
            "is_trashed": false,
            "trashed_on": null,
            "trashed_by_id": 0,
            "created_on": 1430164633,
            "created_by_id": 1,
            "updated_on": 1430164633,
            "updated_by_id": 1,
            "body": null,
            "body_formatted": "",
            "company_id": 1,
            "leader_id": 0,
            "currency_id": 2,
            "template_id": 0,
            "based_on_type": null,
            "based_on_id": null,
            "email": "notifications+m2p-8D4Ijb0@mail.manageprojects.com",
            "is_tracking_enabled": true,
            "is_client_reporting_enabled": false,
            "budget": null,
            "count_tasks": 0,
            "count_discussions": 0,
            "count_files": 0,
            "count_notes": 0
        }
    ],
    "system_notifications": [],
    "job_types": [
        {
            "id": 1,
            "class": "JobType",
            "url_path": "\/job-types\/1",
            "name": "General",
            "is_archived": false,
            "updated_on": null,
            "is_default": true,
            "default_hourly_rate": 100
        }
    ],
    "favorites": []
}
Response: HTTP 200, application/json (Hide)
GET /users/2

Response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
    "single": {
        "id": 2,
        "class": "Member",
        "url_path": "\/users\/2",
        "is_archived": false,
        "is_trashed": false,
        "trashed_on": null,
        "trashed_by_id": 0,
        "created_on": 1430164633,
        "created_by_id": 1,
        "updated_on": 1430164634,
        "updated_by_id": 1,
        "language_id": 0,
        "first_name": "John",
        "last_name": "Doe",
        "display_name": "John Doe",
        "short_display_name": "John D.",
        "email": "first@activecollab.com",
        "additional_email_addresses": [],
        "is_pending_activation": false,
        "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=2&size=--SIZE--&timestamp=1430164634",
        "custom_permissions": [],
        "company_id": 0,
        "title": null,
        "phone": null,
        "im_type": null,
        "im_handle": null,
        "note": null
    }
}

Once invitation is accepted, it is released:

Response: HTTP 404, text/html
GET /accept-invitation

Query Parameters:

1
2
3
4
{
    "user_id": 2,
    "code": "$invitation_code"
}