User Data Management

Store and manage user-specific JSON data such as notes, carts, preferences, or any custom application data. All operations are scoped per user.

searchInUserData

POST /users/:userId/data/search

ParamTypeRequiredDescription
userIdstringYesUser ID
categorystringNoFilter by category
qstringNoSearch text query
keysobjectNoKey-value filtering object
Typescript
1const res = await authix.searchInUserData({
2  userId: "user123",
3  category: "notes",
4  q: "important",       // substring match across the record
5  keys: { status: "open" },  // exact field match
6  limit: 20,
7});
8
9console.log(res.data, res.hasMore, res.nextCursor);

getUserData

GET /users/:userId/data

ParamTypeRequiredDescription
userIdstringYesUser ID
limitnumberNoPagination limit (default 20)
cursorstringNoPagination cursor
categorystringNoFilter by category
Typescript
1const res = await authix.getUserData({
2  userId: "user123",
3  limit: 20,
4  category: "notes",
5  cursor: undefined,
6});
7
8console.log(res.data, res.hasMore, res.nextCursor);

getSingleUserData

GET /users/:userId/data/:dataId

ParamTypeRequiredDescription
userIdstringYesUser ID
dataIdstringYesData item ID
Typescript
1const item = await authix.getSingleUserData({
2  userId: "user123",
3  dataId: "note_1",
4});

Create, Update & Delete

addUserData

POST /users/:userId/data

ParamTypeRequiredDescription
userIdstringYesUser ID
dataCategorystringYesCategory name
dataobjectYesData object
Typescript
1const res = await authix.addUserData({
2  userId: "user123",
3  dataCategory: "notes",
4  data: {
5    title: "My Note",
6    content: "Hello world",
7  },
8});

updateUserData

PUT /users/:userId/data/:dataId

Typescript
1await authix.updateUserData({
2  userId: "user123",
3  dataId: "note_1",
4  data: {
5    title: "Updated title",
6  },
7});
8
9// Pass the version you last read for optimistic concurrency.
10// If someone else changed the record meanwhile, this throws
11// instead of silently overwriting their change.
12try {
13  await authix.updateUserData({
14    userId: "user123",
15    dataId: "note_1",
16    version: note.version,
17    data: { title: "Updated title" },
18  });
19} catch (err) {
20  if (err.isConflict) {
21    // Re-read and retry — err.currentVersion tells you what it is now.
22  }
23}

deleteUserData

DELETE /users/:userId/data/:dataId

Typescript
1await authix.deleteUserData({
2  userId: "user123",
3  dataId: "note_1",
4});
5
6// Or remove several at once, in a single transaction:
7await authix.deleteManyUserData({
8  userId: "user123",
9  dataIds: ["note_1", "note_2", "note_3"],
10});

batch

POST /users/:userId/data-batch

Typescript
1// Every operation commits, or none do.
2// Use this when two records must change together.
3
4await authix.batch({
5  userId: "user123",
6  operations: [
7    { type: "create", dataCategory: "orders", total: 40, status: "paid" },
8    { type: "update", id: stockId, version: 3, remaining: 9 },
9    { type: "delete", id: draftId },
10  ],
11});
12
13// A version mismatch or a missing record aborts the whole batch
14// and nothing is written. Up to 50 operations per call.

Pagination

Reads are always bounded

Every list and search endpoint returns at most limit records — 20 by default, 100 maximum. There is no way to request an unbounded result set, because a single such request on a large app would have to load the entire dataset into memory. Use nextCursor to page through the rest.

Typescript
1// Results are always paginated — limit defaults to 20 and is
2// capped at 100. Follow nextCursor to read the rest.
3
4let cursor;
5do {
6  const page = await authix.getUserData({ userId: "user123", limit: 50, cursor });
7  page.data.forEach(handleRecord);
8  cursor = page.nextCursor;
9} while (cursor);
10
11// Or let the SDK walk the pages for you:
12for await (const page of authix.iterateUserData({ userId: "user123" })) {
13  page.data.forEach(handleRecord);
14}

Best Practices

  • Use consistent dataCategory values for filtering.
  • Do not store sensitive data like passwords or tokens.
  • Use pagination for large datasets.
  • Keep data structure consistent inside each category.
  • Wrap all SDK calls in try/catch for error handling.

Related docs