SYNERGY
Chapters

15.4Requests and responses

Last updated

Format

Requests and responses use JSON (Content-Type: application/json). Property names are camelCase. Dates and times are ISO 8601 in UTC.

Creating an object

A create takes the object's fixed fields and an attributes bag for any other attributes, keyed by their LDAP display names:

http
POST /api/ad/users HTTP/1.1
Host: gateway.example.com
X-API-Key: <your API key>
X-Client-Id: hr-sync
Content-Type: application/json

{
  "name": "Jane Doe",
  "path": "OU=Staff,DC=example,DC=com",
  "samAccountName": "jdoe",
  "password": "<initial password>",
  "accountPolicy": { "enabled": true, "changePasswordAtLogon": true },
  "attributes": {
    "givenName": "Jane",
    "sn": "Doe",
    "mail": "jane.doe@example.com",
    "department": "Finance"
  }
}

A successful create answers 201 Created with the new object and a Location header pointing at it.

The accountPolicy object sets account flags without writing userAccountControl directly. It accepts enabled, passwordNeverExpires, smartcardLogonRequired, trustedForDelegation, accountNotDelegated, passwordNotRequired, cannotChangePassword, allowReversiblePasswordEncryption, changePasswordAtLogon and compoundIdentitySupported. Omitted flags keep their defaults. User and computer updates accept accountPolicy too, and change only the flags you send.

Updating an object

An update names how each attribute changes, using four bags:

http
PATCH /api/ad/users/3f2504e0-4f89-11d3-9a0c-0305e82c3301 HTTP/1.1
Content-Type: application/json

{
  "replace": { "title": "Senior Accountant", "department": "Finance" },
  "add": { "otherTelephone": ["+370 600 00000"] },
  "remove": { "proxyAddresses": ["smtp:old@example.com"] },
  "clear": ["description"]
}
BagEffect
replaceSets the attribute to exactly the given value or values.
addAdds values to a multi-valued attribute.
removeRemoves the listed values.
clearRemoves every value of the listed attributes.

Attributes in the attributes and replace bags are checked against the directory's schema before anything is written. A name the schema does not know, a system-only attribute, an array for a single-valued attribute, or a value of the wrong type is refused with 400 and AD.Attributes.ValidationError.

Security-sensitive attributes are refused in every bag, with the same code: among them userAccountControl (use accountPolicy), servicePrincipalName (use the /spns routes on users and computers, which need ad:spn:manage), adminCount, primaryGroupID, sIDHistory, delegation and resource-based delegation attributes, msDS-KeyCredentialLink, userCertificate, altSecurityIdentities, scriptPath, nTSecurityDescriptor and the password attributes. Reading credential attributes such as LAPS passwords and managed service account passwords through the generic read is refused with 403 and AD.Attributes.ReadForbidden.

An administrator can also protect attributes with attribute policies (Chapter 10, Operation policies, attribute policies and agent supervision). They apply to every caller, API keys and agents included, and nothing is queued for approval:

  • A write — in any bag, or through a typed field such as samAccountName — that touches a read-only or blocked attribute is refused with 403 and AD.Attributes.Protected. metadata.attributes lists each one as { attribute, access, ruleId, reason }. A batch is refused whole, before any item runs.
  • A blocked attribute is left out of every read and of the schema routes. Naming it in a properties list, or testing it in an LDAP filter, is refused with 403 and AD.Attributes.ReadForbidden.
  • The schema routes mark a read-only attribute with isReadOnly: true, access: "ReadOnly" and accessReason.

Searching and paging

Search endpoints take the container to search from and an optional LDAP filter, and return results one page at a time:

http
GET /api/ad/users?baseDn=OU%3DStaff%2CDC%3Dexample%2CDC%3Dcom&ldapFilter=(department%3DFinance)&pageSize=100 HTTP/1.1
ParameterMeaning
baseDnThe container to search from. Required.
ldapFilterAn LDAP filter combined with the object type's own filter.
propertiesAdditional attributes to return; repeat the parameter for several.
pageSizeResults per page. Default 50, maximum 1000.
continuationTokenThe token from the previous page, to fetch the next one.

The response has three parts:

json
{
  "data": [ { "objectGuid": "3f2504e0-4f89-11d3-9a0c-0305e82c3301", "...": "..." } ],
  "meta": { "nextContinuationToken": "…", "pageSize": 100, "hasNextPage": true },
  "links": { "current": "…", "next": "…" }
}

Keep requesting with continuationToken (or follow links.next) until hasNextPage is false.

Last updated

Did this page help you?