Nextcloud Provisioning API
Overview
The Provisioning API enables external systems to create, edit, delete and query user attributes, manage groups, set quotas, query storage, and manage apps. Enabled by default. Uses the OCS API endpoint format.
Base URL: https://nextcloud.example.com/ocs/v1.php/cloud
Auth: Basic HTTP Auth (admin username:password) + OCS-APIRequest header
Headers (required for ALL calls):
Authorization: Basic <base64(admin:password)>OCS-APIRequest: true- POST requests also require
Content-Type: application/x-www-form-urlencoded
Output format: XML by default. Append ?format=json for JSON.
Users
Add a New User
curl -X POST "https://nextcloud.example.com/ocs/v1.php/cloud/users" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "userid=newuser" \
-d "password=SecurePass123!" \
-d "displayName=New User" \
-d "email=newuser@example.com" \
-d "groups[]=admin" \
-d "groups[]=group1" \
-d "quota=10GB"
Status codes: 100=ok, 101=invalid, 102=already exists, 104=group missing
List Users
curl -X GET "https://nextcloud.example.com/ocs/v1.php/cloud/users?search=filter&limit=100&offset=0" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true" | python3 -c "import sys, xml.etree.ElementTree as ET; print('\n'.join(e.text for e in ET.parse(sys.stdin).findall('.//users/element')))"
Get Single User
curl -X GET "https://nextcloud.example.com/ocs/v1.php/cloud/users/newuser" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true" | python3 -c "
import sys, xml.etree.ElementTree as ET
root = ET.parse(sys.stdin).find('.//data')
for child in root:
if child.tag == 'groups':
print(f'{child.tag}: {[e.text for e in child]}')
elif child.text and child.text.strip():
print(f'{child.tag}: {child.text.strip()}')
"
Returns: enabled, id, quota, email, displayname, phone, address, website, twitter, groups.
Edit User
curl -X PUT "https://nextcloud.example.com/ocs/v1.php/cloud/users/newuser" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "key=email" \
-d "value=newemail@example.com"
Editable fields: email, quota, displayname, phone, address, website, twitter, password. Admin can set quota; users can only edit their own email, displayname, password.
Disable User
curl -X PUT "https://nextcloud.example.com/ocs/v1.php/cloud/users/newuser/disable" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true"
Enable User
curl -X PUT "https://nextcloud.example.com/ocs/v1.php/cloud/users/newuser/enable" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true"
Delete User
curl -X DELETE "https://nextcloud.example.com/ocs/v1.php/cloud/users/newuser" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true"
Get User Groups
curl -X GET "https://nextcloud.example.com/ocs/v1.php/cloud/users/newuser/groups" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true"
Add User to Group
curl -X POST "https://nextcloud.example.com/ocs/v1.php/cloud/users/newuser/groups" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "groupid=newgroup"
Remove User from Group
curl -X DELETE "https://nextcloud.example.com/ocs/v1.php/cloud/users/newuser/groups" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "groupid=newgroup"
Promote to Subadmin
curl -X POST "https://nextcloud.example.com/ocs/v1.php/cloud/users/newuser/subadmins" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "groupid=group"
Demote from Subadmin
curl -X DELETE "https://nextcloud.example.com/ocs/v1.php/cloud/users/newuser/subadmins" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "groupid=oldgroup"
Resend Welcome Email
curl -X POST "https://nextcloud.example.com/ocs/v1.php/cloud/users/newuser/welcome" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true"
Groups
List Groups
curl -X GET "https://nextcloud.example.com/ocs/v1.php/cloud/groups?search=adm&limit=50&offset=0" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true"
Create Group
curl -X POST "https://nextcloud.example.com/ocs/v1.php/cloud/groups" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "groupid=newgroup"
Status codes: 100=ok, 101=invalid, 102=already exists
Get Group Members
curl -X GET "https://nextcloud.example.com/ocs/v1.php/cloud/groups/admin" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true"
Returns list of users in the group.
Get Group Subadmins
curl -X GET "https://nextcloud.example.com/ocs/v1.php/cloud/groups/mygroup/subadmins" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true"
Edit Group Display Name
curl -X PUT "https://nextcloud.example.com/ocs/v1.php/cloud/groups/mygroup" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "key=displayname" \
-d "value=My Group Name"
Delete Group
curl -X DELETE "https://nextcloud.example.com/ocs/v1.php/cloud/groups/mygroup" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true"
Does not delete users in the group. Cannot delete the admin group.
Apps
List Apps
curl -X GET "https://nextcloud.example.com/ocs/v1.php/cloud/apps?filter=enabled" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true"
Filter: enabled, disabled, or omit for all.
Get App Info
curl -X GET "https://nextcloud.example.com/ocs/v1.php/cloud/apps/files" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true"
Enable App
curl -X POST "https://nextcloud.example.com/ocs/v1.php/cloud/apps/files_texteditor" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true"
Disable App
curl -X DELETE "https://nextcloud.example.com/ocs/v1.php/cloud/apps/files_texteditor" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true"
Editable Fields Reference
Available via API:
curl -X GET "https://nextcloud.example.com/ocs/v1.php/cloud/user/fields" \
-H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
-H "OCS-APIRequest: true"
Returns: displayname, email, phone, address, website, twitter.
Error Handling
| Status Code | Meaning |
|---|---|
| 100 | Success |
| 101 | Invalid argument / failure |
| 102 | Already exists (user/group) |
| 103 | Cannot create sub-admins for admin group |
| 104 | Group does not exist (user add) / insufficient privileges (user add to group) |
| 105 | Failed to add user to group |
| 106 | No group specified (required for sub-admins) |
| 107 | Password policy violation |
| 108 | Email required for password link |
| 112 | Password change not supported by backend |
| 113 | Editing field not allowed or doesn't exist |
Common Mistakes
- Missing OCS-APIRequest header — Every request needs
OCS-APIRequest: true. Without it, requests return empty responses or 404. - Wrong base path — Use
ocs/v1.php/cloud/, notocs/v2.php/. The v2 path is for the Share API, not Provisioning. - Password with welcome email — Creating a user without a password AND without an email sends no welcome email. Always provide
emailwhen omittingpassword. - XML vs JSON — Default output is XML. For machine parsing, always append
?format=json. Python XML parsing of Nextcloud responses can fail on missing tags. - Group deletion — Deleting a group does not delete its users. Users remain ungrouped.
- Cannot delete admin group — The
admingroup is protected. You cannot remove users from it via API. - POST needs form-urlencoded — POST/PUT requests must use
Content-Type: application/x-www-form-urlencoded. JSON body is not accepted by the OCS API. - Quota format —
unlimitedworks but0does not mean unlimited. Use-3(negative bytes) for unlimited in the API field.
Tips
- JSON output — Append
?format=jsonto any endpoint URL for JSON responses instead of XML - OCS-APIRequest header is mandatory — Without it, requests return empty or 404
- Base URL path —
ocs/v1.php/cloud/(notocs/v2.php/— that's the Share API) - Password-on-create — Leave password empty and provide email to send welcome email with password setup link
- Groups array — Use
groups[]=group1&groups[]=group2for multiple groups in create - Quota format — Supports values like
1GB,500MB,unlimited(or just enternonefor unlimited) - Basic auth — Use the Nextcloud admin user, not an OCC system user
- OCC alternative — For bulk operations or complex config,
occcommand inside the pod is more powerful:kubectl exec deploy/nextcloud -- php occ user:list kubectl exec deploy/nextcloud -- php occ group:add mygroup kubectl exec deploy/nextcloud -- php occ user:add --display-name="Layla Smith" --group="users" layla - App IDs — App ID for the Provisioning API is
provisioning_api(enabled by default); remove it to disable the API - Rate limiting — Nextcloud has no built-in API rate limiting. Add at reverse proxy if needed.