# How AI apps work with YoPrint

> What happens when you ask an AI app for something in YoPrint, things to ask, the limits, and details for developers.

Web page: https://developer.yoprint.com/ai-apps/how-it-works/

## What happens when you ask

You ask in plain words, such as "Which rush orders are due this week?" or "Add 50 black medium t-shirts to order 1042". You don't need to know the API. The app finds what it needs in YoPrint and answers. It works as you: it sees only what your role lets you see.

When you ask for a change, the app should say what it will change and wait for your yes, unless you already asked for exactly that change. YoPrint tells every app to work this way. YoPrint can't see your chat, so it can't check that you agreed. Read what the app says before you say yes.

**Diagram:** Reading needs no go-ahead. A change should wait for yours.

1. **You ask**: "Move order 1042's due date to Friday."
2. **The app looks things up**: It reads the order as you, within your role
3. **The app says what it will change**: "Order 1042: the due date moves to Friday."
4. **You agree**: Unless you already asked for exactly that change
5. **YoPrint saves it**: Under your name, like a change you made in the web app

Where YoPrint keeps a record's history, such as an order's activity, the change shows under your name with "via" and the app's name.

## Things to ask

Each of these works with a **Read and change data** connection, within your role. The ones that only look things up also work with **Read only**.

**Orders and quotes**

- "What are the five newest sales orders, with customer and total?"
- "Find Acme Printing's open quotes and tell me which are older than two weeks."
- "Add 50 black medium t-shirts to order 1042."
- "Move order 1042's in-hands date to next Friday."
- "Turn quote 2210 into a sales order."

**Production schedule**

- "Which jobs are due this week and not started yet?"
- "What jobs aren't scheduled yet?"
- "Schedule the jobs on order 1042 for Tuesday to Thursday."
- "Move job 118 to our Printed status."
- "Put Maria on tomorrow's screen-printing tasks."

**Shipping**

- "Which orders shipped yesterday, and what are their tracking numbers?"
- "Get UPS and USPS rates for order 1042's shipment." This needs GoShippo connected in YoPrint.
- "Buy the cheapest two-day label for it." This spends money: the app should show you the carrier, service and price first.
- "Print the packing slips for today's shipments."

**Purchasing and stock**

- "Which purchase orders are still waiting for delivery?"
- "Make a purchase order to our blanks vendor for what order 1042 needs."
- "Receive purchase order 3301 in full."
- "How many black large t-shirts of style 5000 do we have in stock?"

**Money**

- "Which invoices are unpaid and more than 30 days old, and how much is owed in all?"
- "Record a $150 check payment on order 1042."
- "Send the customer on order 1042 our payment reminder template." This emails the customer: the app should show you the text and recipients first.
- "Run last month's sales report."

What an invoice still owes is its total minus what has been paid, so partly paid invoices count too.

**Customers**

- "Summarize Acme Printing: open orders, what they owe, and their main contact."

For days such as "this week" or "late", the app asks YoPrint for a few extra days, then checks each date against your time zone.

The full list of tasks, area by area, is on [What AI apps can and can't do](https://developer.yoprint.com/ai-apps/capabilities.md).

## Read and change vs. Read only

You choose the access when you approve the connection:

| Connection               | The app can                                                                                 |
| ------------------------ | ------------------------------------------------------------------------------------------- |
| **Read and change data** | Look things up and make changes, up to what your role allows, on a team that allows changes |
| **Read only**            | Look things up, summarize and answer questions. It changes nothing                          |

Your team's setting can narrow it further. See [Your team's AI access](https://developer.yoprint.com/ai-apps/team-ai-access.md).

## Ready-made prompts

YoPrint offers four ready-made prompts. They only read: they never change anything. Apps that support prompts list them in a menu. Claude Code shows them as slash commands.

| Prompt                            | What you get                                                                                                               |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| **Shop briefing** (`briefing`)    | Rush orders and orders due in the next 3 days, late jobs, approvals waiting on customers, and the largest unpaid invoices. |
| **Order status** (`order`)        | Where one order stands: items, production, shipping, invoices and payments, and what is holding it up.                     |
| **Customer summary** (`customer`) | A customer's recent orders and open quotes, what they owe, and who to contact.                                             |
| **What is late** (`late`)         | Orders and jobs past their due date, the most overdue first, with who is assigned.                                         |

## Everyday shop limits

| Limit                                       | How much                                                                                                                               |
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| One call                                    | 30 seconds. A big task takes several calls, which the app makes by itself                                                              |
| Each connection, per minute                 | 600 reads, 120 changes and 30 renders (PDFs and mockup pictures)                                                                       |
| The whole team, per minute                  | 1,200 requests and 60 renders, across every AI app connection                                                                          |
| Changes in one call                         | 25. One change can update several records                                                                                              |
| Files downloaded in one call                | 5 files, up to 10 MB each and 20 MB in all                                                                                             |
| A file from a public link                   | Up to 10 MB, fetched within 20 seconds. An image for a mockup can be up to 120 megapixels. Web pages, scripts and programs are refused |
| A file the app writes itself, such as a CSV | Up to 10 MB                                                                                                                            |

When the app goes over a per-minute limit, YoPrint tells it how many seconds to wait. The app waits, when that fits in the call. Otherwise it stops and tells you when to try again.

### Files you have on your computer

The app can't pass on a file you attach in the chat, such as a logo or a PDF. Its program can only hold about 45 KB of copied text. To add a bigger file:

- put it at a public link that downloads the file itself, not a page about it, and give the app the link, or
- upload it in the YoPrint web app.

## Sign-in and security

- **No copied keys**: you sign in to YoPrint and approve the app. You never paste an API key into another company's tool.
- **Sign-in that renews itself**: the app's access lasts 1 hour and renews in the background. Its renewal lasts 30 days and starts again each time it's used. An app unused for 30 days asks you to sign in again.
- **Stored safely**: YoPrint never keeps the app's sign-in tokens themselves. It keeps only a fingerprint of each one, which can't be turned back into the token.
- **Role checks on every request**: YoPrint checks your membership and your current role each time. If your permissions change or you leave the team, the app follows at once.
- **Fast cutoff**: changing your password or email, or selecting **Logout other devices** in Profile, stops every AI app you connected.
- **Disconnect any time**: **Profile** > **AI apps** > **Disconnect**.

---

## Under the hood (for developers)

The app works through three tools on YoPrint's MCP server. It finds operations with one, then sends a short program with another:

**Diagram:** A program's only way out of its locked box is yoprint.request, and YoPrint checks every request.

1. **search**: The app finds the operations it needs
2. **read or execute**: It sends a short program, which runs in a locked box with no network and no files
3. **yoprint.request**: YoPrint checks each request against the person's role and the team's AI access
4. **Result**: The program's answer, with a receipt for every request

Open a section for the details.

**The three tools**

| Tool      | What it does                                                                                                                                                                                                               | Needs                                                                                       |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| `search`  | Without arguments, a short guide, the connection's details and the families of operations. With words, the best matches in full and the next ones as short rows. It can also show one operation by name, or list a family. | Any active connection                                                                       |
| `read`    | Runs a JavaScript or TypeScript program that reads YoPrint data.                                                                                                                                                           | Any active connection                                                                       |
| `execute` | Runs a program that may also change data and upload files.                                                                                                                                                                 | A **Read and change data** connection on a team that allows changes (`yoprint.write` scope) |

`search` and `read` are marked read-only for the app. `execute` is marked as a tool that changes data, so apps that ask before such tools ask for this one.

**The locked box (sandbox)**

Every `read` and `execute` program runs in a fresh, isolated Deno process:

- **Nothing to reach**: no network, no files, no environment variables, no subprocesses and no native libraries.
- **Size**: the program itself is at most 64 KB.
- **Memory**: a 64 MB heap, and 256 MB for the whole process.
- **Time**: 30 seconds. The process also ends as soon as the app cancels the call.
- **One way out**: `yoprint.request()`, over a private channel to YoPrint, which checks permissions and limits on every request.

**What a program can call**

- `await yoprint.request({ method, path, query, body, idempotencyKey })` sends a request to one operation and answers `{ status, body }`. A refusal that asks it to wait, such as a `429`, also has `retryAfterSeconds`.
- `await yoprint.requestAll([...requests])` runs up to 6 requests at a time.
- `await yoprint.download({ path })` fetches a PDF, CSV or file. The file comes back with the result.
- `await yoprint.upload({ file, body, idempotencyKey })` uploads a file. In `execute` only.
- `await yoprint.operationStatus(key)` says what happened to a change sent with that key.
- `yoprint.shape(value)` describes what a value holds, without its data.
- `yoprint.amount(x)` turns a YoPrint amount into a decimal string.
- `yoprint.connection` names the team, the person (with their timezone) and the access.

**Changes run at most once**

Every change sent through `execute` carries an idempotency key: a UUID the program makes for that one change, so YoPrint can tell a repeat from a new change. A change runs at most once per key. Sending the same key again never runs it, or its emails and payments, a second time:

| The first try                                                  | A repeat with the same key answers                                         | What to do                                                                |
| -------------------------------------------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| Finished (`2xx`)                                               | `409 duplicate_request`, `outcome: "completed"`                            | Nothing. Read the record back to see it                                   |
| Was refused (`4xx`)                                            | `409 duplicate_request`, `outcome: "failed"`, with the first `http_status` | Nothing changed. Fix the request and send it with a new key               |
| Has no known outcome (a `5xx`, a timeout or a lost connection) | `409 outcome_unknown`                                                      | Read the record back. If the change didn't happen, send it with a new key |
| Is still running                                               | `409 request_in_progress`                                                  | Wait, then check with `yoprint.operationStatus(key)`                      |

A used key sent with a different method, path, query or body answers `422 idempotency_key_mismatch`.

Every result ends with a receipt: one entry per request, with its HTTP status and outcome:

| Outcome       | Means                                                                                                             |
| ------------- | ----------------------------------------------------------------------------------------------------------------- |
| `not_started` | Refused before it began, such as a `429` or a permission refusal. Nothing changed                                 |
| `completed`   | Done                                                                                                              |
| `refused`     | Answered `2xx` but said it didn't happen (`success: false`, or `data.valid: false` from publish). Nothing changed |
| `failed`      | Answered `4xx`. Nothing changed                                                                                   |
| `in_progress` | Still running                                                                                                     |
| `unknown`     | No known outcome. Read the record back                                                                            |

**Errors and rate limits**

- Every error YoPrint gives an AI app has `error`, a code such as `rate_limited`, and `message`, one or two sentences on what happened and what to do next. A validation error adds `fields`: each field's name and what is wrong with it.
- A refusal before the change starts also has `outcome: "not_started"`.
- Over a per-minute limit, YoPrint answers `429 rate_limited`, with `Retry-After` in the headers and `retry_after_seconds` in the body. Inside a program, `yoprint.request()` gives it as `retryAfterSeconds`. A program waits that long when it fits in the 30 seconds, otherwise it stops and says when to try again.
- See [Troubleshooting](https://developer.yoprint.com/ai-apps/troubleshooting.md) for every code and what to do.

**More limits**

Beyond the [everyday shop limits](#everyday-shop-limits):

| Limit                     | Value                                                                                                                          |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| Requests in one call      | 100, of which at most 25 changes                                                                                               |
| One request inside a call | 10 seconds, or 60 for an upload or a file from a link                                                                          |
| Response size             | 2 MB for one response, 10 MB in all                                                                                            |
| Result size               | About 6,000 tokens, or about 25,000 with `full: true`                                                                          |
| A program                 | 64 KB of code                                                                                                                  |
| Programs at once          | Up to 8 on each YoPrint MCP server, 4 per team, and 2 per person and per connection. A call waits up to 5 seconds for its turn |
