Personyze Personyze developer docs
Open Personyze
Users

REST Zapier Users object

The users object as consumed by the Personyze integration on Zapier.

Personyze developer documentation Questions: support@personyze.com

For information about how REST API works, see rest main page.

This object is the endpoint used by the Personyze integration on Zapier. It behaves exactly like the users object — same fields, same identity merging, same path parameters — with one difference: POST returns a JSON object {"id": 123} instead of a bare number, because Zapier requires every step to return a JSON object.

The endpoint URL is:

app.personyze.com/rest/zapier_users

Authentication

HTTP "Basic" authentication over HTTPS. Username must be api, the password is your API key. In Zapier the API key is called "password", and is generated in Account settings → Integrations → Zapier. Keys generated for Zapier and keys generated for the Full-featured API are the same set of keys — either one works here.

No special HTTP headers are needed. Request bodies are application/json (application/x-www-form-urlencoded is also accepted).

Methods

Method What it does Returns
POST Insert a user, or merge into an existing user when email or fb_id matches {"id": 123} — the user_id of the inserted or merged record
GET Select users JSON array of user records
PUT Update the users matched by the path parameters Number of affected rows
DELETE Delete the users matched by the path parameters Number of affected rows

Fields

User records don't have a fixed set of columns. Any key-value pair you send is stored. Keys may be written in snake-case (first_name) or camel-case (firstName).

Users carry several identifiers: user_id (assigned by Personyze), internal_id (your own identifier), email, and fb_id. If a POST arrives whose email or fb_id matches a user already in the database, the two records are merged rather than duplicated — this is what makes the Zapier "Create / Update Visitor" step idempotent.

Map your Zapier field to email, not internal_id. On the users object internal_id does not currently match an existing profile, so a sync keyed on it creates a new user on every run. See the note below.

Some field names have special meaning in Personyze (email, first_name, last_name, phone, company, …); everything else is stored as a custom field. To retrieve the list of fields that exist on your account — the list Zapier shows in its field dropdowns — use:

curl 'https://api:FD09908F25BECB09D78EBEA1DADFB618651F612D@app.personyze.com/rest/users_columns'

which returns an array of {"name": ..., "title": ...} objects.

Note on internal_id (current behaviour). On the users object, internal_id is stored and returned, but it does not work as a lookup key: where/internal_id=... matches nothing, a POST carrying an internal_id does not merge into an existing profile (it creates a second one), and requesting internal_id in an explicit columns list returns null. Use email (or the Personyze user_id) as your key. This affects users, zapier_users and user_list_users only — on products and articles, internal_id behaves normally.

Insert example

curl --data '{"first_name": "Johnny", "internal_id": "niceguy-561531", "email": "johnny@gmail.com"}' 'https://api:FD09908F25BECB09D78EBEA1DADFB618651F612D@app.personyze.com/rest/zapier_users'

Response:

{"id": 4412}

Sending a second record with the same email merges into user 4412 and returns the same id:

curl --data '{"first_name": "Big John", "email": "johnny@gmail.com", "phone": "202-555-0152"}' 'https://api:FD09908F25BECB09D78EBEA1DADFB618651F612D@app.personyze.com/rest/zapier_users'

Select example

Path parameters (where, order_by, limit, columns, …) work the same as for every other object — see path parameters.

curl 'https://api:FD09908F25BECB09D78EBEA1DADFB618651F612D@app.personyze.com/rest/zapier_users/where/email=johnny@gmail.com'

Get the most recently changed user (data_last_modified is maintained automatically):

curl 'https://api:FD09908F25BECB09D78EBEA1DADFB618651F612D@app.personyze.com/rest/zapier_users/order_by_desc/data_last_modified/limit/1'

Update example

curl -X PUT --data '{"phone": "202-555-0152"}' 'https://api:FD09908F25BECB09D78EBEA1DADFB618651F612D@app.personyze.com/rest/zapier_users/where/email=johnny@gmail.com'

Delete example

curl -X DELETE 'https://api:FD09908F25BECB09D78EBEA1DADFB618651F612D@app.personyze.com/rest/zapier_users/where/email=johnny@gmail.com'

Response codes and errors

  • 200 OK — request completed. The body is the JSON described in the Methods table above.
  • 400 Bad Request — the request itself was rejected. The body is a plain-text description, e.g. Too many simultaneous requests when POSTs to this account are arriving faster than the account's configured pacing allows, or Couldn't parse input application/json or application/x-www-form-urlencoded.
  • 401 Unauthorized — the API key is invalid or revoked, or the request was not sent over HTTPS.
  • 500 Server Error — internal error. The body contains a description.
  • 503 Temporarily Unavailable — retry the request after a short wait.

Rate limiting

POST requests to this object are serialized per account, and the account may be configured with a pacing delay between consecutive writes. A burst of parallel POSTs may therefore receive 400 Too many simultaneous requests; retry with backoff.

Read limits

Two restrictions apply to every read on this object, and both apply to the users object as well.

1. Reads may only filter on indexed columns. They are:

user_id, last_session_time, data_last_modified, fb_id, email, internal_id

Filtering on anything else is refused with Queries to this object must use indices. These columns have indices: ...

The trap: != fails silently. The rule is only enforced honestly for some operators. where/internal_text_id>'' returns the index error as expected, but where/internal_text_id!='' returns an empty list and no error at all. A filter that silently matches nothing is far more dangerous than one that fails, and != is the form most people reach for first. Note that internal_text_id — the column the panel labels CRM ID — is not in the index list, so it cannot be filtered at all.

2. A filtered read returns at most 50 rows, not 1000:

If not reading consequent rows by index, only first 50 rows can be read

The 1000-row cap applies to unfiltered reads walking an index, where /limit/1000 is the maximum in a single request. Asking for 51 filtered rows fails.

Practical advice: filter, or sort, but expect trouble doing both. Combining the two is unreliable at these limits. The dependable pattern is to read unfiltered along data_last_modified and narrow the result in your own code — which is what the Zapier trigger does.