Skip to content
Documentation
Contents

Building tools

Files, email and people

Store files in buckets, send email, look people up and read your own permissions.

Besides the collections, the interface offers four more things: buckets for files, sending email, the directory of people and information about the signed-in person. The same rules apply to all of them as to data: session cookie, Content-Type: application/json for a JSON body, the same shape of error answer (Reading and writing data).

Enter in tool.json under uses what your tool needs of these: the bucket under buckets, mail.send and people.read under capabilities.

Files in a bucket

A bucket holds files. It stands next to the collections, never inside one. The agent creates it with ensure_bucket. As with data, permissions belong to a role, with the scopes none, own and all for reading and writing. own means the files the person uploaded themselves.

Files are kept per data space, like records: the bucket is the same in both rooms, its contents are not. In the practice room a tool only sees the files uploaded there, see Production and practice room.

CallWhat it does
POST /api/buckets/<bucket>/filesuploads a file
POST /api/buckets/<bucket>/files/querylists files: {"limit": 50} gives {files, total, hasMore}
GET /api/buckets/<bucket>/files/<id>returns the file, always as a download
DELETE /api/buckets/<bucket>/files/<id>deletes the file. The call carries Content-Type: application/json

Uploading a file

The bytes go in the body, the name in the X-File-Name header, percent-encoded. The instance does not accept multipart.

fetch("/api/buckets/belege/files", {
  method: "POST",
  credentials: "same-origin",
  headers: {
    "Content-Type": file.type,
    "X-File-Name": encodeURIComponent(file.name)
  },
  body: file                       // the File object from an <input type="file">
});

The answer is 201 with id, name, mediaType, bytes and checksum.

Limits

  • The default is 25 MB per file and 1 GB per bucket. The quota counts per data space.
  • The instance accepts only certain file types. The default: PDF, PNG, JPEG, GIF, WebP, text, CSV, ZIP, JSON, Word (.docx) and Excel (.xlsx).
  • The instance checks the declared media type against the first bytes. It refuses a file that is called .png and is not one.
  • Every download comes as an attachment. So a stored image cannot be shown with <img src>.
  • A bucket cannot be deleted, its files can.

Sending email

POST /api/mail sends a message. The person needs the capability mail.send through one of their roles.

{
  "to": ["vera@example.com"],
  "subject": "A new task for you",
  "text": "You have a new task: check the offer.",
  "replyTo": "reception@example.com"
}
  • Required are at least one recipient, a subject and a body: text, html or both. cc and bcc are lists like to.
  • The subject is one line of at most 200 characters.
  • The sender is fixed per instance. A tool does not choose it. You can set replyTo.
  • The default is at most 50 recipients per message and 200 messages per hour for the whole instance.
  • Sending happens at once: 202 with {"sent": true} means the message went out. On an error nothing went out.
  • The instance records every message in the audit log.

Looking people up

Do not let anyone type a name. Search the directory and store the id in a field of type person. The person needs the capability people.read. It is not part of admin rights either.

{"term": "ver", "limit": 50}

POST /api/people/query answers:

{"people": [{"id": "…", "name": "Vera Example", "email": "vera@example.com"}],
 "total": 1, "hasMore": false}

GET /api/people/<id> turns a stored id back into a name. The directory holds everyone who has signed in at least once and is not disabled.

Who is signed in

GET /api/me names the signed-in person and their effective permissions:

{
  "userId": "4b40b106-…",
  "name": "Alex Admin",
  "admin": true,
  "roles": ["admin", "demo"],
  "collections": [{"collection": "aufgaben", "read": "all", "write": "all"}],
  "buckets": [{"bucket": "task_files", "read": "all", "write": "all"}],
  "capabilities": ["people.read", "mail.send"],
  "tools": ["tasklist"],
  "contexts": []
}

Use the answer for “my tasks” (created_by equal to userId) and to hide buttons the person may not use. Hiding is a convenience: the instance checks every permission itself on every request.