# Paperarchive - Full Documentation > Paperarchive is an AI-powered document management platform for freelancers and families. Upload any document (PDF, image, or Office file) and it is automatically OCR-processed, categorized, and made searchable. Data is hosted in Germany and processing is GDPR-compliant. The app runs at https://app.paperarchive.io, the public REST API at https://api.paperarchive.io/v1. This file contains the complete help and API documentation in a single Markdown document. A shorter overview is available at https://paperarchive.io/llms.txt, and a machine-readable OpenAPI spec at https://paperarchive.io/docs/openapi.json. All pages are also available as HTML under https://paperarchive.io/docs/ (German: https://paperarchive.io/de/docs/). # Part 1: Help Documentation --- ## Getting Started URL: https://paperarchive.io/docs/getting-started Set up Paperarchive in 5 minutes. Create your account, upload your first document, and see how automatic categorization and OCR search work in practice. # Getting started with Paperarchive Paperarchive turns messy documents into an organized archive, so you always find what you need. If you can forward a file, you can use Paperarchive. ## What you need - A Paperarchive account. - At least one document (PDF, image, or Office document). - Optional: your email client if you want email uploads. ## Quick start (5 minutes) - Create your account (email or Google). - Upload your first document. - Check Documents to see the processed file and review any action hints. - (Optional) Create your first Space. ## Your first upload - Click Upload in the top right. - Drag and drop a file (PDF, image, or Office document), or click to choose. - Wait for processing to finish. You will see the document in the Documents overview. If you prefer email: go to [Settings > Spaces](https://paperarchive.io/docs/spaces-and-email) and use your upload email. ## Where to go next - Documents: your full library with action hints for items that need attention. - Spaces: separate personal and business. - Settings: pick your language and preferences. ## Good first wins - Confirm a sender or category once. Paperarchive will reuse it later. - Add a Space for work vs personal. ## If something looks wrong - Open the document and edit the sender, category, or tags. - Use Undo right after an action if needed. If you want help fast, head to [Contact Support](https://paperarchive.io/docs/contact-support) and drop your email. We will pick it up. --- ## Account & Login URL: https://paperarchive.io/docs/account-and-login Create your Paperarchive account, sign in with email or Google, reset your password, enable two-factor authentication, and manage your active sessions. # Account and login ## Create an account You can sign up with: - Email and password - Google sign-in If you use email, we will send a verification link. Open it to activate your account. Check spam or promotions if you do not see it within a few minutes. ## Log in Go to the login page and use the same method you signed up with. If you used Google, always use the Google button. ## Forgot your password Use "Forgot password" on the login screen. We will send a reset link. The link is single use. If it expires, request a new one. ## Log out Open your profile menu and choose Log out. ## Google sign-in note If you signed up with Google, your email is managed by Google and cannot be changed in the app. --- ## App Overview URL: https://paperarchive.io/docs/app-overview A guided tour of the Paperarchive interface. Learn where to find your inbox, documents, spaces, categories, tags, and settings, and how to navigate fast. # App overview and navigation Paperarchive is split into clear areas so you can move fast. ## Main areas - Documents: your full library with upload, bulk actions, and action hints for items that need attention or clarification. - Search: find documents by keyword or meaning. - Categories, Tags, Senders: clean organization tools. - Spaces: separate contexts (personal, business, shared). - Settings and Profile: preferences, security, data export. - Billing: plan, trial, and limits. - Support: quick access to help. ## What lives where - Trash exists for Documents, Categories, Tags, and Senders. - Profile is for security and data (email, 2FA, export). - Settings is for product behavior (language, notifications). ## Tips - Check action hints in Documents regularly to keep things clean. - Use Spaces when you want a clear separation of topics. - If you cannot find an item, use Search first. --- ## Upload & Documents URL: https://paperarchive.io/docs/upload-and-documents Upload PDFs, images, and Office files to Paperarchive. Supported formats, drag-and-drop and email upload methods, and the basics of managing your archive. # Upload and documents ## What a document is In Paperarchive, a document is the proof. The system extracts the key information behind it (invoice, policy, receipt) and organizes it for you. ## Supported formats - PDF - Images: JPG, JPEG, PNG, TIFF, GIF, WebP, BMP - Office documents: Word (DOC, DOCX), Excel (XLS, XLSX), PowerPoint (PPT, PPTX), OpenDocument (ODT, ODS, ODP) - Max size: 50 MB per file Office documents are automatically converted to PDF for text extraction and viewing. If a file is larger, compress it or split it before upload. ## Upload options - Upload button: top right on Documents. - Drag and drop: drop files into the page. - Email upload: forward emails with attachments (see ["Spaces and Email Upload"](https://paperarchive.io/docs/spaces-and-email)). - Cloud folder: watch a Google Drive or Dropbox folder (see ["Cloud imports"](https://paperarchive.io/docs/cloud-imports)). You can upload multiple files at once. ## What happens after upload - File is validated. - Text is extracted (OCR). - Paperarchive suggests sender, category, tags, date, and filename. - You confirm anything with low confidence. Most files are ready in seconds. Large files can take longer. ## Manage documents - Open a document to preview and edit. - Bulk actions: download, update, or move to trash. - Trash keeps items for 30 days before permanent deletion. ## Common fixes - Wrong sender: edit the sender field and save. - Wrong category or tags: update them in the document view. - Wrong filename: rename it to match your style. --- ## Action Hints URL: https://paperarchive.io/docs/action-hints Paperarchive flags documents that need a quick check. Learn how action hints surface contracts, deadlines, low-confidence results, and unclear sender details. # Action hints When Paperarchive processes a document, it may need your input on certain details. Action hints appear directly in the Documents overview so you can quickly filter and resolve them. ## What are action hints Action hints are visual indicators on documents that need attention. You can select them to filter the documents list, making it easy to focus on what needs action. - Needs attention: time sensitive items (due soon). - Needs your input: Paperarchive needs a quick confirmation on sender, category, or other details. ## Common actions - Confirm: accept Paperarchive's suggestion. - Edit: fix sender, amount, or category. - Mark paid: for invoices. - Archive: file away. ## Undo After most actions you will see a toast with Undo for a few seconds. Use it right away if you clicked the wrong action. --- ## Processing & AI URL: https://paperarchive.io/docs/processing-and-ai Inside the Paperarchive pipeline: OCR text extraction, AI categorization, tag suggestions, and structured data extraction run automatically on every upload. # Processing and AI Paperarchive automatically processes every document you upload using AI-powered analysis. ## How processing works - Validate file type and size. - OCR extracts text from PDFs and images. - Paperarchive extracts sender, category, tags, dates, and summary. - Similarity matching connects related documents. Low confidence results create action hints on the document so you can review and confirm. ## Duplicate detection Paperarchive automatically detects duplicate uploads using SHA-256 content hashing. When you upload a file, a hash is computed on your device and verified on the server. If the same content already exists in your library, the upload is skipped and you are notified. For near-duplicates (re-scans, reformatted versions), Paperarchive uses embedding similarity to flag documents that are very similar to existing ones. These are marked for your review so you can decide whether to keep them. Duplicate detection works across all upload methods: the app, the API, and email forwarding. ## Processing language Pick the language that best matches your documents. This improves OCR and extraction. Display language is separate and only affects the app UI. ## What Paperarchive detects - Sender: the company or person the document is from. - Category: the type of document (invoice, contract, etc.). - Tags: relevant labels extracted from the content. - Date: the document date (not the upload date). - Filename: a clean, descriptive name based on the content and your [naming preferences](https://paperarchive.io/docs/settings-and-profile). You can always edit any of these after processing. --- ## Search URL: https://paperarchive.io/docs/search Find any document in seconds using keyword search, full-text matching, semantic similarity, and filters by category, tag, sender, or date in Paperarchive. # Search Search is fast and smart. Use a few words and let Paperarchive do the rest. ## Search basics - Keyword search for exact terms. - Smart search for meaning and related content. - Results highlight matching text. Examples: - "telekom invoice" - "insurance 2024" - "electricity december" ## Filters and sorting Use filters to narrow by: - Date - Category - Tag - Sender - Space Tip: start broad, then narrow with filters. --- ## Categories URL: https://paperarchive.io/docs/categories Organize your archive with categories and nested subcategories. Paperarchive suggests categories automatically and lets you create custom ones per space. # Categories Categories are your main filing system. Use them for big buckets like "Utilities" or "Insurance". Paperarchive can suggest categories, and you can always override them. Use categories for stable structure, and tags for flexible labels. ## Create a category - Go to Categories. - Click New category. - Name it and save. You will see the document count next to each category. ## Subcategories (one level) You can add subcategories under a top level category. Nested levels deeper than one are not supported. This keeps navigation fast and clean. ## Edit and organize - Rename: change the label. - Move: move a category under another (when allowed). - Merge: combine multiple categories into one. Note: categories with children may have move restrictions. ## Trash and restore Deleted categories go to Trash for 30 days. You can restore or delete permanently. --- ## Tags URL: https://paperarchive.io/docs/tags Use tags as flexible cross-cutting labels for your documents. Combine them with categories to filter, search, and group records across any Paperarchive space. # Tags Tags are flexible labels that cut across categories, like "tax", "warranty", or "travel". They are great for topics that appear in many categories. ## Tags vs keywords - Keywords are terms Paperarchive extracts from a single document. - Tags are curated labels that appear in filters. Keywords are searchable, but only tags show up as filters. ## Manage tags - Create: add a tag manually. - Rename: update the label. - Merge: combine similar tags. - Trash: remove, with 30 day restore window. --- ## Senders URL: https://paperarchive.io/docs/senders How Paperarchive detects senders on invoices and letters, learns your renaming preferences, and groups documents by sender across every space. # Senders Senders are companies or people that send you documents. Paperarchive detects them automatically. You can also create a sender manually. ## When a sender needs review New or low confidence senders appear as "needs review". Use the Unconfirmed filter to review them fast. You can confirm a single sender or confirm all. Confirming a sender makes future documents easier to file. ## Manage senders - Rename: fix spelling or preferred name. - Merge: combine duplicates. - Trash: remove, with 30 day restore window. If a document shows the wrong sender, edit it from the document view. Tip: keeping senders clean improves future auto filing. --- ## Spaces & Email Upload URL: https://paperarchive.io/docs/spaces-and-email Separate personal and business documents with spaces, and forward incoming receipts straight to Paperarchive via a unique email address per space. # Spaces and email upload Spaces let you separate areas like Personal, Business, or a specific project. Each space also has its own email address for uploads. ## What is a space Think of a space as a clean bucket for documents. You can switch spaces in the app or view all spaces at once. The default space is where uploads go if no space is specified. ## Create or edit a space - Go to Settings > Spaces. - Click Create space. - Pick a name, type, color, and emoji. You can set a default space and reorder spaces. If you delete a space, you choose where its documents should be moved. Space names can be changed later, and the email address updates with it. Each space can also have GoBD-compliant archiving enabled under the Advanced section in space settings. This adds automatic document archiving, retention periods, and deletion protection for all documents in that space. See the [GoBD compliance](https://paperarchive.io/docs/gobd-compliance) article for details. ## Email upload You get: - One primary upload email (goes to your default space). - One unique email per space (goes directly there). Find them in Settings > Spaces and copy with one click. You can also download a vCard to save them in contacts. Use space emails when you want routing without extra clicks. ### Rules that matter - Only attachments are processed (PDF or images). - Max size is 50 MB per file. - Emails are accepted only from your registered email address. - Do not share your upload addresses. If you need a specific space, use its address. If not, use the primary one. --- ## Cloud Imports URL: https://paperarchive.io/docs/cloud-imports Connect Google Drive or Dropbox, pick a folder to watch, and let Paperarchive import new documents from it automatically. # Cloud imports from Google Drive and Dropbox Connect Google Drive or Dropbox, pick one folder, and Paperarchive imports new files from it on its own. You can connect both services at the same time and watch one folder in each. ## Connect a service - Go to Settings > Integrations. - Click Connect Google Drive or Connect Dropbox. - Approve the read-only access on the provider's consent screen. - Search for the folder you want to watch and select it. Nothing is imported until you pick a folder. Until then the integration is connected but idle. ## What gets imported - Only files that sit directly in the folder you picked. Subfolders are ignored. - The same formats as a manual upload: PDF, images, and Office documents (see ["Upload and documents"](https://paperarchive.io/docs/upload-and-documents)). - Max 50 MB per file. - Large batches are imported in chunks of up to 25 files per sync run; the remainder follows automatically in the next runs. ## How often it syncs Paperarchive checks your watched folder about every 15 minutes, so a new file usually shows up within that window. If you do not want to wait, open Settings > Integrations and click Sync now. The same page shows the last sync time and the last error, if there was one. ## Where imported documents land Imported files go into your default space and run through exactly the same processing as a manual upload: text extraction (OCR), then suggestions for sender, category, tags, date, and filename. Anything with low confidence turns into an action hint, just like usual. ## Duplicates Paperarchive compares file content, not file names. If a file is already in your archive, it is skipped, even if it was renamed or copied. That also means switching the watched folder back and forth does not create duplicates. ## Access and privacy - Paperarchive asks for read-only access. It never changes, moves, or deletes anything in your cloud storage. - Your files stay where they are. Paperarchive imports a copy. - Access tokens are stored server-side and never reach your browser. - Disconnecting revokes the access token at the provider. ## Change the folder or disconnect You can pick a different folder at any time. The next sync then looks at the new folder from scratch. When you disconnect a service, documents that were already imported stay in Paperarchive, but no new files are imported. ## If nothing is imported - Check Last sync and the error line in Settings > Integrations. - The file type is not supported, or the file is larger than 50 MB. - The file sits in a subfolder of the watched folder. - The document is already in your archive. - More than 25 new files arrived at once. The remainder is imported automatically over the following runs (about every 15 minutes). - If the error mentions the connection or a token, disconnect and connect the service again. --- ## Shared Spaces URL: https://paperarchive.io/docs/shared-spaces Collaborate with family, partners, or your team in shared Paperarchive spaces. Invite members by email, manage roles and permissions, and keep an edit history. # Shared Spaces Shared Spaces let you collaborate with other people inside a single space. Invite family members, colleagues, or your accountant and control exactly what they can do. ## What is a shared space A shared space works like any other space, but with multiple users. Everyone who has access sees the same documents, categories, tags, and senders inside that space. Each member has a role that controls their permissions. The person who creates the space is the Owner. Owners can invite others and manage the space. Shared Spaces is a Premium feature. You need an active Premium plan or trial to create and manage shared spaces. ## Create a shared space - Go to Settings > Spaces. - Click Create space. - Pick a name, type, color, and emoji. Any space you create can be shared. After creation, open the space settings and go to Members to start inviting people. ## Invite members - Go to Settings > Spaces and select the space. - Click Members. - Click Invite Member. - Enter the email address, optionally a display name, and choose a role. - Click Send Invitation. The invited person receives an email with a link. If they already have a Paperarchive account, they can accept right away. If not, they can sign up first and then accept. You can cancel a pending invitation at any time from the Members page. ## Roles and permissions Every member of a shared space has one of four roles. The table below shows what each role can do. | Permission | Viewer | Editor | Admin | Owner | | --- | --- | --- | --- | --- | | View documents | ✓ | ✓ | ✓ | ✓ | | Search documents | ✓ | ✓ | ✓ | ✓ | | Upload documents | | ✓ | ✓ | ✓ | | Edit document details | | ✓ | ✓ | ✓ | | Move documents in/out | | ✓ | ✓ | ✓ | | Delete documents | | ✓ | ✓ | ✓ | | Invite new members | | | ✓ | ✓ | | Change member roles | | | ✓ | ✓ | | Remove members | | | ✓ | ✓ | | Cancel pending invitations | | | ✓ | ✓ | | Edit space settings | | | ✓ | ✓ | | Delete the space | | | | ✓ | | Transfer ownership | | | | ✓ | Owner - Full control. Every space has exactly one owner. Owners cannot leave their own space - they must delete it instead. Admin - Can manage members and settings, but cannot delete the space or transfer ownership. Editor - Can view and edit documents, upload new ones, and move documents in and out. Cannot manage members or settings. Viewer - Read-only access. Can view and search documents but cannot upload, edit, or move anything. ## Moving documents You can move documents between spaces you have access to. ### Moving documents into a shared space Select one or more documents, click Move, and choose the shared space as the target. You need at least Editor permissions in the target space. ### Moving documents out of a shared space Select documents in the shared space, click Move, and choose a personal space or another shared space where you have Editor or higher permissions. Documents that are GoBD-archived cannot be moved. ### Who sees what after a move When you move a document into a shared space, all members can see it (according to their role). When you move a document out to your personal space, other members lose access. ## Leaving a shared space - Go to Settings > Spaces and select the shared space. - Click Members. - Click Leave at the bottom of the page. You will immediately lose access to all documents in that space. If you want to keep specific documents, move them to a personal space before leaving. Owners cannot leave their own space. To remove a shared space, the owner must delete it. ## Free plan members and shared spaces Shared Spaces is a Premium feature. However, members who are on the Free plan can still be invited to and use a shared space owned by a Premium user: - The shared space runs on the owner's subscription. Document limits, AI features, and storage are counted against the owner's plan. - A Free plan user invited to a shared space can view, search, and (if they have the Editor role) edit documents in that shared space. - The Free plan member's own spaces and documents are still subject to their Free plan limits (100 documents, no AI, no smart search). - If the Free plan member only uses Paperarchive through shared spaces, they do not need to upgrade. ### What happens if the owner cancels their subscription - Uploads stop: No one can upload new documents to the shared space. - Documents stay: Existing documents remain accessible in read-only mode. - Editing stops: Members can no longer edit, move, or delete documents. - The space still exists: Once the owner reactivates their Premium plan, full access is restored automatically. ## Email upload in shared spaces Each space has its own upload email address. In a shared space, the upload email routes documents directly into the shared space. Only the owner's email address is accepted for email uploads. Members cannot use their own email address to send documents to a shared space via email - they should use the upload button instead. ## Tips - Use shared spaces for household documents, small business paperwork, or projects with external partners. - Assign the Viewer role to people who only need to look up documents (like an accountant reviewing receipts). - Assign the Editor role to people who actively add and organize documents. - Use the Admin role sparingly - only for people who should also manage members. --- ## Settings & Profile URL: https://paperarchive.io/docs/settings-and-profile Configure processing preferences, interface language, two-factor authentication, account security, and full data export from your Paperarchive profile. # Settings and profile ## Settings Go to Settings to control how Paperarchive works. You can change: - Processing language (OCR and extraction) - Document naming template - Display language (English or German) - Timezone - Email notifications (processing updates and product updates) Changes apply to future documents, not ones already processed. ### Document naming Choose how the AI names your documents. Pick a template or build your own: - Compact: document type with date (e.g. "Invoice Feb 2026"). - Detailed: adds reference numbers (e.g. "Invoice RE-2026-0042 Feb 2026"). - With Sender: includes the sender name (e.g. "Cloudflare Invoice RE-2026-0042 Feb 2026"). - Custom: toggle sender, date, date format, and reference number individually. The default is Compact. Since the sender is a separate searchable field, it is not included in the name by default. A live preview shows exactly what names will look like. ### Smart dates in filenames Paperarchive adapts the date in the filename to how a document recurs, so dates only show up where they actually distinguish documents: - One-time documents (e.g. a purchase contract or a one-off receipt) get no date in the name. - Yearly documents (e.g. a tax assessment or annual statement) get only the year (e.g. "2026"). - Monthly documents (e.g. a payslip, utility bill, or bank statement) get month and year as before. The recurrence type is detected automatically. You can change it on any document - it updates the metadata (used for things like reminders for yearly documents) but does not rename the existing file, so your filenames stay stable. ## Profile Go to Profile for account and security. ### Change email If you did not sign up with Google, you can change your email. You will need to confirm the change via links sent to both addresses. If you used Google, the change is managed by Google. ### Two factor authentication (2FA) - Click Enable 2FA. - Scan the QR code with an authenticator app. - Enter the 6 digit code. - Optional: add a backup authenticator. If you lose access to both apps, you may lose access to your account. ### Data export Request an export from Profile > Data and Privacy. We will email you a secure download link. If the link expires, you can request a new export. ### Delete account Start the deletion flow in Profile > Data and Privacy. We will email a confirmation link. This cannot be undone. --- ## Billing & Plans URL: https://paperarchive.io/docs/billing-and-plans Compare Paperarchive plans, start your free trial, track included credits, change your tier, and manage your subscription and invoices from one dashboard. # Billing, trial, and plans Check your plan status in Billing. ## Plans at a glance - Trial: 30 days of full access. - Premium: unlimited documents and all Paperarchive features. - Free: up to 100 documents with basic organization. ## What happens after trial If payment succeeds, you keep full access. If payment fails, you enter a grace period with read only access. During grace period you can upgrade, or switch to Free and keep your 100 most recent documents. ## Free plan limit Free accounts can keep 100 documents. If you are over the limit, extra documents are locked (not deleted). You can unlock everything by upgrading. ## Credits and notifications Some accounts use document credits (subscription or one time packs). If credit notifications are enabled, we email you when you reach 10 credits. You can manage notification settings in Settings. ## Manage subscription Use the Billing page to open the customer portal and update payment details. You can also cancel or change your plan from there. --- ## AI Assistants (MCP) URL: https://paperarchive.io/docs/mcp-connector Connect Paperarchive to your AI assistant and chat with your documents: search your archive, ask about invoices and contracts, and get download links - straight from a conversation. Works with Claude, ChatGPT, and Grok. # Chat with your documents in your AI assistant Paperarchive connects to AI assistants as an MCP connector. Once linked, you can ask things like "Find my phone contract", "How much was the electricity bill in March?", or "List my latest bank statements" - and your assistant looks it up in your archive for you. The connector works with any assistant that supports custom MCP connectors, including Claude, ChatGPT, and Grok. ## What your assistant can do - Search your documents by content, sender, category, or tag. - Read document details like amounts, dates, and extracted text. - Look up transactions from processed bank statements. - Answer "What is open or due?" using the events Paperarchive extracts - invoices, contracts, and policies with state, amount, and due date. - Give you a short-lived download link for the original file. The connection is read-only: a connected assistant can never create, change, or delete documents in your archive. ## What you need - A Paperarchive Premium plan (or an active trial) - the same requirement as for API keys. - An assistant plan that supports custom connectors (all three assistants require a paid plan for this). ## How connecting works The flow is the same everywhere: add this URL as a custom connector in your assistant, and you will be sent to Paperarchive to approve the connection. ``` https://api.paperarchive.io/mcp ``` - Add the URL in your assistant (exact steps per assistant below). - You are redirected to Paperarchive. Log in if needed. - Review the permissions, choose which Spaces the assistant may access, and click Allow access. - Back in your assistant, enable the connector in a chat and start asking questions. You can also find the URL with a copy button in the app under [Settings](https://paperarchive.io/docs/settings-and-profile) > API Keys > Connected Apps. ### Claude In Claude (claude.ai or the desktop app), open Settings > Connectors, click Add custom connector, and paste the URL. On Team/Enterprise plans an admin adds the connector in the organization settings. ### ChatGPT In ChatGPT on the web, enable Developer mode under Settings > Apps > Advanced settings (on some accounts the toggle is under Settings > Connectors > Advanced). Then add a new connector with the URL and complete the approval flow. ### Grok Open [grok.com/connectors](https://grok.com/connectors), click New Connector, choose Custom, and paste the URL. ## Choosing Spaces During approval you decide which Spaces the connection can see, for example only your business Space. Everything outside the selected Spaces stays invisible to the assistant - this is enforced on the server, not just in the interface. ## Privacy - A connected assistant only receives what its tools request: search results, document details, and statement data from the Spaces you approved. - Document content that an assistant reads becomes part of your conversation with that assistant. Treat conversations with the same care as the documents themselves. - You stay in control: disconnecting stops all access immediately. ## Disconnecting Go to Settings > API Keys > Connected Apps in Paperarchive and click Disconnect next to the app. The assistant immediately loses access. You can reconnect at any time. ## Troubleshooting - The assistant asks to re-authenticate: the login expired after longer inactivity. Just run the connect flow again. - The assistant cannot find a document: check that the document's Space was selected when you connected, and that processing has finished. - Upgrade notice during connect: the connector needs an active Premium or trial plan. Developers find the technical details (OAuth, tools, Claude Code setup) in the [API documentation](https://paperarchive.io/docs/api/mcp-connector). --- ## Learning & Feedback URL: https://paperarchive.io/docs/learning-and-feedback How Paperarchive learns from your edits. Sender renames, category corrections, and tag tweaks feed back into the model so future uploads get sharper over time. # Learning and feedback Paperarchive learns from your edits so it gets better over time. ## How learning works When you edit a document, we record: - Sender changes - Category changes - Tag changes - Filename patterns Those patterns are reused for similar documents. The more consistent you are, the faster results improve. ## Give feedback In the document view you can: - Confirm Paperarchive's suggestions - Edit fields - Trigger reprocessing Every confirmation or correction helps future results. ## Learning page Open Settings > Learning to see: - Patterns learned - Accuracy rate - Recent learning activity Learning data is private to your account. --- ## Content Policy & Privacy URL: https://paperarchive.io/docs/content-policy-and-privacy Which content is allowed in Paperarchive and how your data is protected. Covers acceptable use, prohibited material, encryption, and hosting in Germany. # Content policy and privacy ## Content policy We do not allow documents that contain: - Adult content - Violent content - Racy content - Spoofed or manipulated content If a file violates the policy, it is removed during processing and you will see an error. We do not keep the content. ## Privacy basics - Your files are stored in private storage. - Only you can access your documents. - We do not share your data with other users. If an upload fails, double check file type and size. If you have questions about data handling, [contact support](https://paperarchive.io/docs/contact-support). --- ## GoBD Compliance URL: https://paperarchive.io/docs/gobd-compliance GoBD-compliant document archiving in Paperarchive with mandatory retention periods, audit trail, and deletion protection for tax-relevant business records. # GoBD compliance GoBD (Grundsätze zur ordnungsmäßigen Führung und Aufbewahrung von Büchern, Aufzeichnungen und Unterlagen in elektronischer Form) is a German regulation for digital document archiving. Paperarchive supports GoBD-compliant document management on a per-space basis. When enabled, Paperarchive automatically archives documents, applies retention periods, protects archived documents from changes, and logs all modifications to an immutable audit trail. ## Who needs GoBD GoBD applies to all taxpayers in Germany who keep digital records. If you run a business, are self-employed, or manage tax-relevant documents digitally, GoBD rules apply to you. The key requirements are: - Documents must be stored unaltered for the legally required retention period. - Changes must be traceable through an audit trail. - Documents must not be deleted before the retention period expires. - The integrity of stored files must be verifiable. ## How to enable GoBD for a space GoBD is a per-space setting. Each space can independently have GoBD enabled or disabled. Documents inherit GoBD rules from the space they belong to. - Go to Settings > Spaces. - Click the space you want to configure. - Expand the Advanced section at the bottom of the modal. - Toggle GoBD-compliant archiving on. - Click Save. GoBD can only be enabled on existing spaces, not during space creation. You can also disable GoBD for a space by toggling it off and saving. Disabling GoBD removes the compliance rules for future documents but does not retroactively change documents that were already archived. ## What happens when GoBD is enabled When you enable GoBD for a space, every document uploaded to that space is automatically processed with the following compliance features. ### Automatic archiving After Paperarchive finishes processing a document (OCR, AI analysis, categorization), the document is automatically archived. You do not need to archive documents manually. Once archived, the document is locked and its core fields cannot be changed. ### Retention periods A retention period is automatically applied based on the document type that Paperarchive detects during analysis. The retention period starts at the end of the calendar year of the document date, not the upload date. For example, an invoice dated March 15, 2024 has a retention period that starts on December 31, 2024 and expires on December 31, 2034 (10 years). The following retention periods apply: | Document type | Retention | Legal basis | | --- | --- | --- | | Invoices | 10 years | HGB 257, AO 147 | | Receipts | 10 years | HGB 257, AO 147 | | Contracts | 10 years | HGB 257 | | Insurance policies | 10 years | HGB 257 | | Bank statements | 10 years | HGB 257, AO 147 | | Letters and correspondence | 6 years | HGB 257, AO 147 | | Notices and official documents | 6 years | AO 147 | If a document type is not listed above, a default retention period of 10 years is applied. ### File integrity A SHA-256 hash is computed for every uploaded file. This hash acts as a digital fingerprint and serves two purposes: integrity verification and duplicate detection. If the stored file were ever altered, the hash would no longer match, making tampering detectable. The hash is also used to prevent duplicate uploads across your library. Hashes are computed both on the client (during upload) and on the server (during processing) and compared to ensure upload integrity. The hash, the algorithm used, and the timestamp of computation are stored alongside the document. File hashing is active for all documents regardless of the GoBD setting. ### Audit trail Every change to a document is automatically logged to an immutable audit trail. This includes changes to: - Document name - Document content - Sender - Category - Space assignment - Document date - Deletion status - Archive status - File hash The audit trail is append-only. Log entries cannot be edited or deleted, even by administrators. This ensures a complete, tamper-proof history of every document action. Audit logging is active for all documents regardless of the GoBD setting. ## What is protected after archiving Once a document is archived in a GoBD-enabled space, the following fields are permanently locked and cannot be changed: - The document content (extracted text) - The original filename - The document date - The assigned sender - The assigned category - The file hash - The stored file itself - The deletion status (cannot be soft-deleted or restored) Fields that remain editable after archiving include tags, processing hints, and other non-core metadata. ## Deletion rules GoBD enforces strict rules about when documents can be deleted. ### Documents that cannot be deleted - A document that has been archived in a GoBD-enabled space cannot be deleted. This is permanent. - A document with an active retention period (the retention expiry date is in the future) cannot be deleted, even if it has not been archived yet. These rules are enforced at the database level. They cannot be bypassed through the UI or the API. ### Documents that can be deleted - Documents in spaces without GoBD enabled can always be deleted, regardless of their archive or retention status. - Documents whose retention period has expired and that have not been archived can be deleted. ### When you move a document between spaces If you move a document from a GoBD-enabled space to a regular space, the document's existing archive status and retention period remain on the document record. However, the GoBD guard rules only apply while the document is in a GoBD-enabled space. Moving it to a non-GoBD space effectively removes the deletion protection. If you move a document into a GoBD-enabled space, it will be subject to GoBD rules going forward but will not be automatically archived. Only documents processed in a GoBD space receive automatic archiving. ## Things to know - GoBD is per space, not per document. All documents in a GoBD-enabled space follow the same rules. - Archiving happens automatically after processing. You do not need to trigger it manually. - Archived documents are permanently locked. There is no way to un-archive a document. - The minimum retention period under GoBD is 6 years (for business correspondence). Most document types require 10 years. - File hashing and audit logging are always active for all documents across all spaces. Enabling GoBD adds archiving, retention enforcement, and deletion protection on top of that. - Disabling GoBD on a space does not retroactively remove archive locks or retention periods from documents that were already archived. ## Process documentation For a full technical description of how Paperarchive implements GoBD compliance - including data flows, security measures, and legal references - see the [process documentation](https://paperarchive.io/compliance-documentation). --- ## Contact Support URL: https://paperarchive.io/docs/contact-support How to reach Paperarchive support fast: in-app chat, email, response times by plan, and the quickest path to help with billing or technical questions. # Contact support Need help? Reach out from the app or email us directly. ## Fastest way - Open Support in the app sidebar. - Add your email address (name is optional). - Submit your question. That is it. We will get back to you by email. ## Help us help you Include: - What you tried - The exact error message - A screenshot (if possible) - The document name or ID (from the URL) # Part 2: API Reference --- ## Introduction URL: https://paperarchive.io/docs/api/introduction Overview of the Paperarchive REST API: base URL, versioning, rate limits, request and response format, and what you can build on top of your document archive. # Introduction The Paperarchive API is a REST API that lets you integrate document management into any workflow - upload, search, categorize, and retrieve documents programmatically. It is designed for automations, integrations, and building custom workflows on top of your document archive. Prefer chatting instead of coding? Paperarchive also ships an [MCP connector](https://paperarchive.io/docs/api/mcp-connector) that plugs your archive straight into AI assistants like Claude, ChatGPT, and Grok. ## Base URL All API requests are made to: ``` https://api.paperarchive.io/v1 ``` ## Versioning The API is versioned via the URL path. The current version is `v1`. When breaking changes are introduced, a new version will be released while the previous version remains available for a deprecation period. ## Request Format Most request bodies are JSON-encoded with the `Content-Type: application/json` header. The exception is `POST /v1/documents` which accepts `multipart/form-data` for file uploads. Query parameters are used for filtering and pagination on GET endpoints. ## Response Format Most responses return JSON with a consistent envelope: ``` { "success": true, "data": { ... }, "total": 42, "limit": 50, "offset": 0 } ``` The download endpoint `GET /v1/document/:id/download` responds with a `302` redirect to a short-lived signed download URL - make sure your HTTP client follows redirects (e.g. `curl -L`). On errors, the response includes an error message: ``` { "success": false, "error": "Description of what went wrong" } ``` ## Quick Start Make your first API call by listing your documents: ``` curl -H "Authorization: Bearer pa_live_YOUR_KEY" \ https://api.paperarchive.io/v1/documents ``` You'll need an API key - see the [Authentication](https://paperarchive.io/docs/api/authentication) page for how to create one. ## Integration Quick Starts Connect Paperarchive to your favorite automation tools and start building powerful document workflows in minutes. [🤖 OpenClaw + Paperarchive Let your AI assistant manage documents autonomously - upload, search, and organize files through natural conversation via WhatsApp, Telegram, or Slack. Get started ->](https://paperarchive.io/docs/api/openclaw-quickstart) [⚡ n8n + Paperarchive Build visual document automation workflows - process invoices from email, sync with accounting tools, and trigger AI analysis on autopilot. Get started ->](https://paperarchive.io/docs/api/n8n-quickstart) --- ## Authentication URL: https://paperarchive.io/docs/api/authentication Authenticate against the Paperarchive API with personal API keys passed as Bearer tokens. Manage your keys, rotate them, and scope access to specific spaces. # Authentication The Paperarchive API uses Bearer token authentication with API keys. Every request must include your API key in the `Authorization` header. ## Creating an API Key Create and manage API keys in the Paperarchive app at [Settings > API Keys](https://app.paperarchive.io/settings#api-keys). Each key can be scoped to specific permissions and spaces. ## Using Your API Key Include the key in the `Authorization` header as a Bearer token: ``` Authorization: Bearer pa_live_abc123def456... ``` ## Key Format API keys use the prefix `pa_live_` followed by a random string. The full key is only shown once at creation time - store it securely. ## Scopes Each API key is assigned scopes that control what it can access. Available scopes: | Scope | Description | | --- | --- | | `documents:read` | List and retrieve documents | | `documents:write` | Create and delete documents | | `search` | Search across documents | | `events:read` | List and retrieve events (open items, due dates) | | `spaces:read` | List and retrieve spaces | | `categories:read` | List categories | | `categories:write` | Create and delete categories | | `tags:read` | List tags | | `tags:write` | Create and delete tags | | `senders:read` | List senders | | `senders:write` | Create and delete senders | ## Space Restrictions API keys can optionally be restricted to specific spaces. When restricted, the key can only access documents, categories, tags, and senders within those spaces. ## Security Best Practices - Use the minimum scopes needed for your integration - Restrict keys to specific spaces when possible - Rotate keys periodically - Never expose keys in client-side code or public repositories - Revoke compromised keys immediately --- ## Documents URL: https://paperarchive.io/docs/api/documents Endpoints to list, retrieve, download, upload, and delete documents in Paperarchive. With pagination, filters, multipart upload, and per-endpoint rate limits. ### GET /v1/documents List documents with pagination and optional filters. Results are scoped to spaces accessible by your API key. Required scope: `documents:read` Query parameters: - `limit` (integer, optional, default: 50): Number of documents to return (1-100). - `offset` (integer, optional, default: 0): Number of documents to skip for pagination. - `sort_by` (string, optional, default: created_at, one of: created_at, updated_at, title, document_date): Field to sort by. - `sort_order` (string, optional, default: desc, one of: asc, desc): Sort direction. - `space_id` (uuid, optional): Filter by space ID. - `category_id` (uuid, optional): Filter by category ID. - `status` (string, optional, one of: pending, processing, completed, failed, skipped): Filter by document status. - `created_after` (string (ISO 8601), optional): Filter documents created after this timestamp (e.g. "2026-03-30T10:00:00Z"). Useful for incremental syncs. Response example: ```json { "success": true, "data": [ { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "title": "Invoice #2026-001", "document_date": "2026-01-15", "category_id": "cat-uuid-here", "sender_id": "sender-uuid-here", "space_id": "space-uuid-here", "file_type": null, "file_size": null, "status": "completed", "event_type": "invoice", "amount": 1200.00, "currency": "EUR", "structured_data": { "line_items": [ { "description": "Consulting services", "quantity": 1, "unit_price": 1200, "total": 1200, "tax_rate": 19 } ], "tax_breakdown": { "net_amount": 1008.40, "tax_amount": 191.60, "tax_rate": 19, "gross_amount": 1200 }, "payment_method": "bank_transfer", "order_number": "ORD-2026-042", "delivery_date": null, "recurring": null }, "created_at": "2026-01-15T10:30:00Z", "updated_at": "2026-01-15T10:32:00Z" } ], "total": 142, "limit": 10, "offset": 0 } ``` Response fields: - `id` (uuid): Unique document identifier. - `title` (string): Document title (AI-generated or user-set). - `document_date` (date): Date of the document (extracted or manual). - `category_id` (uuid | null): Assigned category ID. - `sender_id` (uuid | null): Identified sender ID. - `space_id` (uuid): Space the document belongs to. - `file_type` (string | null): MIME type of the uploaded file. Currently always null - reserved for a future release. - `file_size` (integer | null): File size in bytes. Currently always null - reserved for a future release. - `status` (string): Processing status: pending, processing, completed, failed, or skipped. Skipped means the document was not processed (duplicate or content policy). - `event_type` (string | null): AI-classified document type: invoice, offer, credit_note, contract, policy, statement, notice, receipt, payslip, letter, or null if not yet processed. - `amount` (number | null): Extracted monetary amount (e.g. invoice total, salary). - `currency` (string | null): ISO currency code for the amount (e.g. EUR, USD). - `structured_data` (object | null): Type-specific extracted metadata. Fields vary by event_type - see Structured Data section below. - `created_at` (datetime): When the document was created. - `updated_at` (datetime): When the document was last updated. ### GET /v1/document/:id/download Download the original file for a document by ID. Responds with a 302 redirect to a short-lived signed download URL (valid for 60 seconds) with a Content-Disposition attachment filename. Make sure your HTTP client follows redirects (curl -L; fetch and requests follow them by default). Alias: /v1/documents/:id/download. Requires access to the document space. Required scope: `documents:read` Path parameters: - `id` (uuid, required): The document ID. Response example: ```json { "success": true, "data": { "note": "This endpoint responds with a 302 redirect to a short-lived signed download URL. Following the redirect returns the binary file, not JSON." } } ``` ### GET /v1/documents/:id Retrieve a single document by ID, including the full OCR text, extracted structured data, and tags. Only accessible if the document is in a space your API key can access. Required scope: `documents:read` Path parameters: - `id` (uuid, required): The document ID. Response example: ```json { "success": true, "data": { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "title": "Invoice #2026-001", "document_date": "2026-01-15", "category_id": "cat-uuid-here", "sender_id": "sender-uuid-here", "space_id": "space-uuid-here", "file_type": null, "file_size": null, "status": "completed", "event_type": "invoice", "amount": 1200.00, "currency": "EUR", "structured_data": { "line_items": [ { "description": "Consulting services - January 2026", "quantity": 1, "unit_price": 1200, "total": 1200, "tax_rate": 19 } ], "tax_breakdown": { "net_amount": 1008.40, "tax_amount": 191.60, "tax_rate": 19, "gross_amount": 1200 }, "payment_method": "bank_transfer", "order_number": "ORD-2026-042", "delivery_date": null, "recurring": null }, "ocr_text": "Invoice #2026-001\nDate: January 15, 2026\nFrom: Acme Corp...", "ai_title": null, "ai_summary": null, "tags": ["invoice", "acme-corp"], "created_at": "2026-01-15T10:30:00Z", "updated_at": "2026-01-15T10:32:00Z" } } ``` Response fields: - `event_type` (string | null): AI-classified document type: invoice, offer, credit_note, contract, policy, statement, notice, receipt, payslip, or letter. - `amount` (number | null): Extracted monetary amount (e.g. invoice total, salary). - `currency` (string | null): ISO currency code for the amount (e.g. EUR, USD). - `structured_data` (object | null): Type-specific extracted metadata. Fields vary by event_type - see Structured Data section below. - `ocr_text` (string | null): Full OCR-extracted text from the document. - `ai_title` (string | null): AI-generated title. Currently always null - reserved for a future release; use title instead. - `ai_summary` (string | null): AI-generated summary. Currently always null - reserved for a future release; use ocr_text and structured_data instead. - `tags` (string[]): Array of tag names associated with the document. ### POST /v1/documents Upload a document file (PDF, image, or Office document). The file is stored securely and automatically processed through the OCR / AI pipeline - text extraction, metadata analysis, categorization, and embeddings all happen automatically. Send as multipart/form-data. File content is validated server-side via magic-byte signatures. The resolved target space is always checked for write access. Rate-limited to 10 uploads per minute. You can optionally pass a metadata JSON string to pre-populate document properties. Metadata you provide takes precedence over AI-extracted values - the AI still runs to fill in any gaps. Required scope: `documents:write` Body parameters: - `file` (file, required): PDF, JPEG, PNG, TIFF, or Office document (DOCX, DOC, PPTX, PPT, XLSX, XLS, ODT, ODS, ODP). Max 50 MB. Content is validated by magic bytes - the Content-Type header must match the actual file content. - `space_id` (uuid, optional): Target space. Falls back to your default space if omitted. API keys restricted to specific spaces can only upload to those spaces. - `metadata` (JSON string, optional): Optional JSON string with custom metadata to pre-populate on the document. Your values take precedence over AI extraction. Supported fields: event_type (invoice, receipt, contract, policy, notice, payslip, letter, statement, offer, credit_note), state_hint (open, paid, active, expired), amount ({ value: number, currency: string }), sender_name (string), document_date (YYYY-MM-DD or ISO 8601), due_date (YYYY-MM-DD), paid_at (YYYY-MM-DD - marks the document as paid and creates a confirmed payment record), reference_number (string), tags (string array, max 5), category (string - category name), title (string - document title override). When paid_at is provided, the event is created directly in the "paid" state with a confirmed payment record - no manual confirmation needed. This is useful when your system already knows the payment status. Response example: ```json { "success": true, "message": "Document uploaded and processing started.", "data": { "id": "new-doc-uuid-here", "name": "invoice.pdf", "processing_state": "pending", "space_id": "space-uuid-here", "created_at": "2026-03-07T14:20:00Z" } } ``` Response fields: - `id` (uuid): Unique document identifier. - `name` (string): Original filename. - `processing_state` (string): Processing status: pending, processing, completed, error, or skipped. Skipped means the document was not processed because it is a duplicate or was blocked by content policy. - `space_id` (uuid): Space the document was uploaded to. - `created_at` (datetime): When the document was created. ### DELETE /v1/documents/:id Soft-delete a document. The document is marked as deleted but can be recovered. Only works for documents in spaces accessible by your API key. Required scope: `documents:write` Path parameters: - `id` (uuid, required): The document ID to delete. Response example: ```json { "success": true } ``` --- ## Statements URL: https://paperarchive.io/docs/api/statements Retrieve extracted transactions, balances, IBAN, period, and bank metadata from processed bank statements. Polling-friendly with a since parameter for incremental syncs. ### GET /v1/statements List bank statement documents with extracted transaction data. Supports incremental polling via the "since" parameter. Only statements whose structured_data has been populated are returned. Required scope: `documents:read` Query parameters: - `since` (string (ISO 8601), optional): Filter by updated_at >= since. Useful for incremental syncs (e.g. "2026-03-30T10:00:00Z"). - `limit` (integer, optional, default: 100): Maximum number of statements to return (1-500). Response example: ```json { "success": true, "data": [ { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "name": "Kontoauszug March 2026", "original_name": "Kontoauszug_20260331.pdf", "original_created_at": "2026-03-31", "updated_at": "2026-04-01T10:30:00Z", "created_at": "2026-04-01T10:25:00Z", "structured_data": { "opening_balance": 10412.24, "closing_balance": 15279.34, "opening_balance_date": "2026-02-28", "closing_balance_date": "2026-03-31", "account_iban": "DE27500105175410883100", "statement_period": { "start": "2026-03-01", "end": "2026-03-31" }, "auszugsnummer": "3", "bank_name": "ING", "currency": "EUR", "transaction_count": 45, "extracted_at": "2026-04-01T10:29:45Z", "transactions": [ { "date": "2026-03-02", "value_date": "2026-03-02", "amount": -1000.00, "currency": "EUR", "counterparty": "Julia Klein", "counterparty_iban": null, "reference": "Haushaltsgeld", "type": "debit", "transaction_type": "Dauerauftrag" } ] } } ], "count": 1 } ``` Response fields: - `id` (uuid): Document ID of the bank statement. - `name` (string): Document title. - `original_name` (string): Original uploaded filename. - `original_created_at` (date): Statement date (extracted). - `updated_at` (datetime): When the statement was last updated - useful for incremental polling. - `created_at` (datetime): When the document was uploaded. - `structured_data` (object): Extracted statement data. See the Structured Data section for the full field reference. ### GET /v1/statements/:id/transactions Retrieve the full extracted transactions and statement metadata (balances, IBAN, period, bank name) for a single bank statement document. Required scope: `documents:read` Path parameters: - `id` (uuid, required): The bank statement document ID. Response example: ```json { "success": true, "data": { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "name": "Kontoauszug March 2026", "original_name": "Kontoauszug_20260331.pdf", "original_created_at": "2026-03-31", "updated_at": "2026-04-01T10:30:00Z", "structured_data": { "opening_balance": 10412.24, "closing_balance": 15279.34, "account_iban": "DE27500105175410883100", "statement_period": { "start": "2026-03-01", "end": "2026-03-31" }, "bank_name": "ING", "currency": "EUR", "transaction_count": 45, "transactions": [ { "date": "2026-03-27", "value_date": "2026-03-27", "amount": 13502.53, "currency": "EUR", "counterparty": "KIRCHHOFF Automotive Deutschland GmbH", "counterparty_iban": null, "reference": "Verdienstabrechnung 03.26", "type": "credit", "transaction_type": "Gehalt" } ] } } } ``` Response fields: - `id` (uuid): Statement document ID. - `name` (string): Document title. - `structured_data` (object): Full extracted statement data. See the Structured Data section for field details. --- ## Events URL: https://paperarchive.io/docs/api/events Query the events Paperarchive extracts from documents - invoices, contracts, policies, notices, and more - including state, amount, and due date. Ideal for questions like "What is open or due?". ### GET /v1/events List events extracted from documents. Each event carries a state (e.g. "open", "paid", "active"), an optional amount, and an optional due date, and links to its source document. Events are visible when their linked document is in an accessible space; events without a document are not returned. Required scope: `events:read` Query parameters: - `state` (string, optional): Filter by state: received, needs_input, open, paid, expired, cancelled, archived, active. - `event_type` (string, optional): Filter by type: invoice, offer, credit_note, statement, contract, policy, notice, receipt, payslip, letter. - `due_before` (date (YYYY-MM-DD), optional): Only events with a due date on or before this date. - `due_after` (date (YYYY-MM-DD), optional): Only events with a due date on or after this date. - `space_id` (uuid, optional): Only events whose document is in this space. - `document_id` (uuid, optional): Only events attached to this document. - `limit` (integer, optional, default: 25): Maximum number of events to return (1-100). - `offset` (integer, optional, default: 0): Pagination offset. Response example: ```json { "success": true, "data": [ { "id": "e1f2a3b4-c5d6-7890-abcd-ef1234567890", "event_type": "invoice", "state": "open", "state_changed_at": "2026-07-20T09:15:00Z", "needs_input_reason": null, "occurred_at": "2026-07-18T00:00:00Z", "due_date": "2026-08-15", "period_start": null, "period_end": null, "amount": 89.90, "amount_type": "payable", "currency": "EUR", "amount_confirmed": true, "skonto_percent": 2.00, "skonto_amount": 88.10, "skonto_due_date": "2026-07-28", "reference_number": "RE-2026-1042", "summary": "Electricity bill July 2026", "sender": { "id": "b2c3d4e5-f6a7-8901-bcde-f23456789012", "name": "Stadtwerke" }, "document": { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "title": "Stadtwerke_Rechnung_Juli.pdf", "space_id": "c3d4e5f6-a7b8-9012-cdef-345678901234" }, "created_at": "2026-07-20T09:14:00Z", "updated_at": "2026-07-20T09:15:00Z" } ], "total": 1, "limit": 25, "offset": 0 } ``` Response fields: - `id` (uuid): Event ID. - `event_type` (string): Event type (invoice, contract, policy, ...). - `state` (string): Current state in the event lifecycle. - `due_date` (date): Payment or action deadline, if any. - `amount` (number): Monetary amount, if any. - `skonto_due_date` (date): Early-payment discount deadline, if extracted. - `sender` (object): Sender of the underlying document ({ id, name }), if detected. - `document` (object): Linked source document ({ id, title, space_id }). ### GET /v1/events/:id Retrieve a single event by ID, including amounts, deadlines, reference number, sender, and the linked source document. Required scope: `events:read` Path parameters: - `id` (uuid, required): The event ID. Response example: ```json { "success": true, "data": { "id": "e1f2a3b4-c5d6-7890-abcd-ef1234567890", "event_type": "invoice", "state": "open", "due_date": "2026-08-15", "amount": 89.90, "currency": "EUR", "reference_number": "RE-2026-1042", "summary": "Electricity bill July 2026", "sender": { "id": "b2c3d4e5-f6a7-8901-bcde-f23456789012", "name": "Stadtwerke" }, "document": { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "title": "Stadtwerke_Rechnung_Juli.pdf", "space_id": "c3d4e5f6-a7b8-9012-cdef-345678901234" } } } ``` --- ## Structured Data URL: https://paperarchive.io/docs/api/structured-data Reference for the type-specific structured_data object returned on Paperarchive documents, including invoice, receipt, bank statement, and contract shapes. # Structured Data Every processed document includes an `event_type`, `amount`, `currency`, and a `structured_data` object with type-specific fields extracted by AI. The fields vary depending on the document's `event_type`. If the document has not been processed yet or the type could not be determined, all fields are `null`. ## invoice | Field | Type | Description | | --- | --- | --- | | `line_items` | `[{ description, quantity, unit_price, total, tax_rate }]` | Individual line items on the invoice. | | `tax_breakdown` | `{ net_amount, tax_amount, tax_rate, gross_amount }` | Tax calculation summary. | | `payment_method` | `string | null` | One of: bank_transfer, direct_debit, card, paypal. | | `order_number` | `string | null` | Referenced order or purchase number. | | `delivery_date` | `YYYY-MM-DD | null` | Delivery or service date. | | `recurring` | `{ is_recurring, frequency } | null` | Whether this is a recurring invoice (monthly, quarterly, yearly). | ## offer | Field | Type | Description | | --- | --- | --- | | `line_items` | `[{ description, quantity, unit_price, total }]` | Offered line items. | | `valid_until` | `YYYY-MM-DD | null` | Offer expiration date. | | `terms` | `string | null` | Brief summary of key terms. | ## credit_note | Field | Type | Description | | --- | --- | --- | | `original_invoice_ref` | `string | null` | Reference to the original invoice. | | `reason` | `string | null` | Reason for the credit note. | | `line_items` | `[{ description, quantity, unit_price, total }]` | Credited line items. | ## contract | Field | Type | Description | | --- | --- | --- | | `contract_type` | `string` | One of: rental, employment, service, insurance, subscription, other. | | `parties` | `[{ name, role }]` | Contract parties and their roles. | | `start_date` | `YYYY-MM-DD | null` | Contract start date. | | `end_date` | `YYYY-MM-DD | null` | Contract end date. | | `termination_notice` | `{ period_months, deadline } | null` | Notice period and deadline for termination. | | `auto_renewal` | `boolean | null` | Whether the contract auto-renews. | | `monthly_cost` | `{ value, currency } | null` | Monthly cost if applicable. | | `key_terms` | `[string]` | 1-3 key terms summarized as bullet points. | ## policy | Field | Type | Description | | --- | --- | --- | | `policy_type` | `string` | One of: health, liability, property, vehicle, life, legal, other. | | `insured_object` | `string | null` | What is insured. | | `coverage_amount` | `{ value, currency } | null` | Maximum coverage amount. | | `deductible` | `{ value, currency } | null` | Deductible amount. | | `premium_frequency` | `string | null` | Payment frequency: monthly, quarterly, semi-annual, annual. | | `cancellation_deadline` | `YYYY-MM-DD | null` | Deadline to cancel the policy. | ## notice | Field | Type | Description | | --- | --- | --- | | `notice_type` | `string` | One of: price_change, termination, renewal, rate_adjustment, information, warning, other. | | `effective_date` | `YYYY-MM-DD | null` | When the notice takes effect. | | `action_required` | `boolean` | Whether the recipient needs to act. | | `action_deadline` | `YYYY-MM-DD | null` | Deadline for required action. | | `previous_value` | `string | null` | Previous value (e.g. old price). | | `new_value` | `string | null` | New value (e.g. new price). | ## receipt | Field | Type | Description | | --- | --- | --- | | `payment_method` | `string | null` | One of: cash, card, bank_transfer, paypal, other. | | `items` | `[{ description, amount }]` | Purchased items. | | `location` | `string | null` | Store or purchase location. | | `tax_breakdown` | `{ net_amount, tax_amount, tax_rate } | null` | Tax calculation summary. | ## payslip | Field | Type | Description | | --- | --- | --- | | `employer` | `string | null` | Employer name. | | `pay_period` | `{ start, end } | null` | Pay period date range (YYYY-MM-DD). | | `gross_salary` | `{ value, currency } | null` | Gross salary amount. | | `net_salary` | `{ value, currency } | null` | Net salary amount. | | `deductions` | `[{ description, amount, type }]` | Deductions with type: tax, social_security, insurance, other. | | `bonuses` | `[{ description, amount }]` | Bonus payments. | | `hours_worked` | `number | null` | Hours worked in the period. | | `tax_class` | `string | null` | Tax class (German: Steuerklasse). | ## letter | Field | Type | Description | | --- | --- | --- | | `letter_type` | `string` | One of: information, request, complaint, confirmation, reminder, other. | | `response_required` | `boolean` | Whether a response is expected. | | `response_deadline` | `YYYY-MM-DD | null` | Deadline to respond. | ## statement Bank statements (`event_type = "statement"`) are processed by a dedicated extraction pipeline that parses transactions, balances, and statement metadata. The extracted data is returned as `structured_data`, and is also available via dedicated endpoints (see the [Statements](https://paperarchive.io/docs/api/statements) section). | Field | Type | Description | | --- | --- | --- | | `opening_balance` | `number | null` | Starting balance (Alter Saldo), signed. | | `closing_balance` | `number | null` | Ending balance (Neuer Saldo), signed. | | `opening_balance_date` | `YYYY-MM-DD | null` | Date of the opening balance. | | `closing_balance_date` | `YYYY-MM-DD | null` | Date of the closing balance. | | `account_iban` | `string | null` | IBAN of the account the statement belongs to. | | `statement_period` | `{ start, end } | null` | Statement period as ISO 8601 dates. | | `auszugsnummer` | `string | null` | Statement number if present. | | `bank_name` | `string | null` | Detected bank (e.g. ING, Sparkasse, Kontist). | | `currency` | `string` | Statement currency, defaults to EUR. | | `transactions` | `[{ date, value_date, amount, currency, counterparty, counterparty_iban, reference, type, transaction_type }]` | Extracted transactions. `type` is `debit` or `credit`; `transaction_type` is the raw bank label (Lastschrift, Dauerauftrag, Kartenzahlung, etc.). | | `transaction_count` | `number` | Number of extracted transactions. | | `extracted_at` | `datetime` | When the extraction ran. | --- ## Search URL: https://paperarchive.io/docs/api/search Full-text search across every document in spaces accessible to your API key. Results ranked by relevance, with support for keyword, phrase, and filter queries. ### POST /v1/search Search across all accessible documents using full-text search. Returns matching documents ranked by relevance. Required scope: `search` Body parameters: - `query` (string, required): Search query text. - `limit` (integer, optional, default: 20): Maximum results to return (1-50). - `space_id` (uuid, optional): Limit search to a specific space. Response example: ```json { "success": true, "data": [ { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "title": "Invoice #2026-001 from Acme Corp", "document_date": "2026-01-15", "space_id": "space-uuid-here", "status": "completed", "rank": 0.95 } ], "total": 3 } ``` --- ## Spaces URL: https://paperarchive.io/docs/api/spaces Endpoints to list and retrieve the spaces your API key can access. Spaces organize Paperarchive documents into separate collections like Personal or Business. ### GET /v1/spaces List all spaces accessible by your API key. Spaces organize documents into separate collections (e.g. "Personal", "Business"). Required scope: `spaces:read` Response example: ```json { "success": true, "data": [ { "id": "space-uuid-1", "name": "Personal", "type": "personal", "color": "#3b82f6", "is_default": true, "created_at": "2025-06-01T08:00:00Z" }, { "id": "space-uuid-2", "name": "Business", "type": "custom", "color": "#10b981", "is_default": false, "created_at": "2025-07-15T12:00:00Z" } ] } ``` Response fields: - `id` (uuid): Unique space identifier. - `name` (string): Space display name. - `type` (string): Space type (personal, custom). - `color` (string): Hex color code for the space. - `is_default` (boolean): Whether this is the default space. - `created_at` (datetime): When the space was created. ### GET /v1/spaces/:id Retrieve a single space by ID. Required scope: `spaces:read` Path parameters: - `id` (uuid, required): The space ID. Response example: ```json { "success": true, "data": { "id": "space-uuid-1", "name": "Personal", "type": "personal", "color": "#3b82f6", "is_default": true, "created_at": "2025-06-01T08:00:00Z" } } ``` --- ## Categories URL: https://paperarchive.io/docs/api/categories Endpoints to list, create, and delete categories in Paperarchive. Categories are user-owned and assigned to spaces via the category_spaces model. ### GET /v1/categories List categories you own that are linked to any accessible space (legacy categories.space_id or rows in category_spaces). Each item includes membership_space_ids for all linked spaces. Required scope: `categories:read` Response example: ```json { "success": true, "data": [ { "id": "cat-uuid-1", "name": "Invoices", "color": "#ef4444", "icon": "receipt", "space_id": null, "membership_space_ids": ["space-uuid-1", "space-uuid-2"] }, { "id": "cat-uuid-2", "name": "Contracts", "color": "#8b5cf6", "icon": "document-text", "space_id": null, "membership_space_ids": ["space-uuid-1"] } ] } ``` Response fields: - `id` (uuid): Unique category identifier. - `name` (string): Category display name. - `color` (string): Hex color code. - `icon` (string): Icon name. - `space_id` (uuid | null): Legacy single-space column. Often null; prefer membership_space_ids. - `membership_space_ids` (uuid[]): Spaces this category is assigned to via category_spaces. ### POST /v1/categories Create a category and assign it to a space. If space_id is omitted, your default space is used (when it exists). Required scope: `categories:write` Body parameters: - `name` (string, required): Category name. - `space_id` (uuid, optional): Target space for the first membership. Omit to use your default space. - `color` (string, optional): Hex color code (e.g. "#ef4444"). - `icon` (string, optional): Icon name. Response example: ```json { "success": true, "data": { "id": "new-cat-uuid", "name": "Receipts", "color": "#f59e0b", "icon": null, "space_id": null, "membership_space_ids": ["space-uuid-1"] } } ``` ### DELETE /v1/categories/:id Delete a category you own when it is linked to at least one space your key can access (category_spaces or legacy space_id). Required scope: `categories:write` Path parameters: - `id` (uuid, required): The category ID to delete. Response example: ```json { "success": true } ``` ## Smoke test checklist (categories API) Use a test API key with `categories:read` and `categories:write` (and `spaces:read` so you can resolve space UUIDs). Run against staging or local API. - GET /v1/categories - Expect `200`, `success: true`, array `data`. Each item has `membership_space_ids` (array, possibly empty for legacy rows before backfill). - POST with explicit space_id - `POST /v1/categories` with body `{"name":"API Smoke Cat","space_id":""}`. Expect `201`, returned `membership_space_ids` contains that space. - POST without space_id - Same with only `{"name":"API Smoke Cat Default"}`. Expect `201` if a default space exists, or `400` with a clear error if not. - GET again - New category appears; `membership_space_ids` matches the space you used (or default). - DELETE - `DELETE /v1/categories/` with the new id. Expect `200` and `success: true`. Repeat GET to confirm it is gone. - Restricted API key - With a key limited to one space, repeat POST targeting a space outside the key: expect `403`. --- ## Tags URL: https://paperarchive.io/docs/api/tags Endpoints to list, create, and delete tags. Tags are flexible cross-cutting labels that complement categories on every document in your Paperarchive archive. ### GET /v1/tags List all tags across accessible spaces. Tags provide flexible labeling for documents beyond categories. Required scope: `tags:read` Response example: ```json { "success": true, "data": [ { "id": "tag-uuid-1", "name": "urgent", "space_id": "space-uuid-1" }, { "id": "tag-uuid-2", "name": "tax-2026", "space_id": "space-uuid-1" } ] } ``` Response fields: - `id` (uuid): Unique tag identifier. - `name` (string): Tag name. - `space_id` (uuid): Space this tag belongs to. ### POST /v1/tags Create a new tag in a space. Required scope: `tags:write` Body parameters: - `name` (string, required): Tag name. - `space_id` (uuid, required): Space to create the tag in. Response example: ```json { "success": true, "data": { "id": "new-tag-uuid", "name": "important", "space_id": "space-uuid-1" } } ``` ### DELETE /v1/tags/:id Delete a tag. Only works for tags in spaces accessible by your API key. Required scope: `tags:write` Path parameters: - `id` (uuid, required): The tag ID to delete. Response example: ```json { "success": true } ``` --- ## Senders URL: https://paperarchive.io/docs/api/senders Endpoints to list, create, and delete senders. A sender represents the company or person on incoming Paperarchive invoices, contracts, and letters. ### GET /v1/senders List all senders across accessible spaces. Senders are automatically detected from documents by AI or can be manually assigned. Required scope: `senders:read` Response example: ```json { "success": true, "data": [ { "id": "sender-uuid-1", "name": "Acme Corp", "space_id": "space-uuid-1" }, { "id": "sender-uuid-2", "name": "Deutsche Telekom", "space_id": "space-uuid-1" } ] } ``` Response fields: - `id` (uuid): Unique sender identifier. - `name` (string): Sender name. - `space_id` (uuid): Space this sender belongs to. ### POST /v1/senders Create a new sender in a space. Required scope: `senders:write` Body parameters: - `name` (string, required): Sender name. - `space_id` (uuid, required): Space to create the sender in. Response example: ```json { "success": true, "data": { "id": "new-sender-uuid", "name": "Acme Corp", "space_id": "space-uuid-1" } } ``` ### DELETE /v1/senders/:id Delete a sender. Only works for senders in spaces accessible by your API key. Required scope: `senders:write` Path parameters: - `id` (uuid, required): The sender ID to delete. Response example: ```json { "success": true } ``` --- ## OpenClaw Integration URL: https://paperarchive.io/docs/api/openclaw-quickstart Learn how to integrate Paperarchive with OpenClaw to build an AI-powered document assistant that uploads, searches, and organizes documents through natural language via WhatsApp, Telegram, Slack, and more. # OpenClaw + Paperarchive: Build an AI Document Assistant [OpenClaw](https://openclaws.io/) is an open-source AI assistant platform with 234,000+ GitHub stars that turns large language models into autonomous agents capable of taking real action - browsing the web, managing files, sending messages, and calling APIs. By connecting OpenClaw with the Paperarchive API, you can build a personal AI document assistant that manages your entire document archive through natural conversation on WhatsApp, Telegram, Slack, Discord, or any supported messaging channel. This guide walks you through a complete end-to-end setup: from installing OpenClaw and configuring Paperarchive API access, to building practical skills that let your AI assistant upload receipts from a photo, search for tax documents by asking a question, and automatically organize incoming files into the right categories. ## Why Combine OpenClaw with Paperarchive? Paperarchive already provides AI-powered document processing - automatic OCR, categorization, sender detection, and full-text search. OpenClaw adds a conversational interface layer on top, so instead of opening the Paperarchive app and navigating through menus, you simply message your assistant: - "Upload this invoice" - snap a photo on your phone and send it via WhatsApp. OpenClaw forwards it to Paperarchive, which handles OCR and categorization automatically. - "Find my electricity bill from January" - OpenClaw calls the Paperarchive search API and returns the matching document with a summary. - "How much did I spend on insurance this year?" - OpenClaw searches across all your documents, extracts amounts, and calculates a total. - "Create a new category called Medical" - OpenClaw calls the categories API and confirms the result. The combination turns document management from a chore into something that happens in the background while you go about your day. ## Prerequisites Before you start, you will need: - A Paperarchive account with an active subscription. [Sign up free](https://app.paperarchive.io/register) if you do not have one yet. - A Paperarchive API key with the scopes you want your assistant to use. Create one at [Settings > API Keys](https://app.paperarchive.io/settings#api-keys). For a full-featured assistant, enable all scopes: `documents:read`, `documents:write`, `search`, `spaces:read`, `categories:read`, `categories:write`, `tags:read`, `tags:write`, `senders:read`. - A machine to run OpenClaw - this can be your laptop, a home server, or a cloud VPS. OpenClaw supports macOS, Windows, and Linux. - An API key for an LLM provider - [Anthropic](https://www.anthropic.com/) (Claude), [OpenAI](https://openai.com/) (GPT), or a local model via [Ollama](https://ollama.com/). ## Step 1: Install OpenClaw OpenClaw runs on your own machine with your data staying private by default. Install it using one of these methods: ### Quick Install (macOS / Linux) ``` curl -fsSL https://get.openclaws.io | bash ``` ### Using Docker ``` docker run -d --name openclaw \ -p 3838:3838 \ -v openclaw-data:/data \ openclaws/openclaw:latest ``` ### From Source ``` git clone https://github.com/openclaw/openclaw.git cd openclaw npm install npm start ``` After installation, open the OpenClaw dashboard (usually at `http://localhost:3838`) and complete the initial setup by providing your LLM API key. ## Step 2: Configure the Paperarchive API Connection OpenClaw uses environment variables and configuration files to manage credentials securely. Add your Paperarchive API key to the OpenClaw configuration: ### Option A: Environment Variable ``` export PAPERARCHIVE_API_KEY="pa_live_your_key_here" export PAPERARCHIVE_BASE_URL="https://api.paperarchive.io/v1" ``` ### Option B: OpenClaw Config File In your OpenClaw configuration file (typically `~/.openclaw/config.json`), add: ``` { "secrets": { "paperarchive_api_key": "pa_live_your_key_here" }, "env": { "PAPERARCHIVE_BASE_URL": "https://api.paperarchive.io/v1" } } ``` Verify the connection by asking OpenClaw to make a test call: ``` curl -H "Authorization: Bearer pa_live_your_key_here" \ https://api.paperarchive.io/v1/documents?limit=1 ``` If you get a JSON response with `"success": true`, you are good to go. ## Step 3: Create the Paperarchive Skill OpenClaw extends its capabilities through skills - modular instructions and tool definitions that teach the assistant how to interact with external services. Create a Paperarchive skill that gives OpenClaw full access to your document archive. Create a file called `paperarchive.skill.md` in your OpenClaw skills directory: ``` # Paperarchive Document Management You have access to the Paperarchive API for document management. Use it when the user asks about documents, invoices, receipts, contracts, or files. ## API Base URL ${PAPERARCHIVE_BASE_URL} ## Authentication All requests require: Authorization: Bearer ${PAPERARCHIVE_API_KEY} ## Available Actions ### Search Documents POST /search Body: { "query": "search terms", "limit": 10 } Use this when the user asks to find, look up, or search for documents. ### List Documents GET /documents?limit=50&sort_by=created_at&sort_order=desc Use when the user wants to see recent documents or browse their archive. ### Upload Document POST /documents (multipart/form-data) Fields: file (required), space_id (optional) Use when the user sends a photo or file to be archived. ### Get Document Details GET /documents/:id Use to retrieve full details including OCR text and structured data. ### List Categories GET /categories Use when the user asks about available categories. ### Create Category POST /categories Body: { "name": "Category Name", "space_id": "uuid" } ### List Spaces GET /spaces Use when the user asks about their spaces or workspaces. ### Search and Summarize When the user asks a question about their documents (e.g. "how much did I spend on..."), search for relevant documents, read their OCR text, and provide a helpful summary. ## Response Guidelines - Always confirm successful uploads with the document title - When listing documents, format them in a readable list - When searching, highlight the most relevant results - If no results found, suggest alternative search terms ``` Place this file in your OpenClaw skills directory (typically `~/.openclaw/skills/`) and restart OpenClaw or reload skills from the dashboard. ## Step 4: Connect a Messaging Channel The real power of this integration is being able to manage documents from your phone. OpenClaw supports multiple messaging channels out of the box: ### WhatsApp Connect your WhatsApp number through the OpenClaw dashboard under Channels > WhatsApp. Once connected, you can send photos of receipts and documents directly to your assistant, and it will upload them to Paperarchive automatically. ### Telegram Create a Telegram bot via [@BotFather](https://t.me/BotFather) and add the bot token to OpenClaw. Telegram's file sharing capabilities make it ideal for sending PDFs and images. ### Slack / Discord For teams using Slack or Discord, connect your workspace to create a shared document assistant that the entire team can use. ## Step 5: Test the Integration Once everything is connected, try these commands with your assistant: ### Upload a Document Send a photo of a receipt or invoice to your assistant. OpenClaw will: - Receive the image from your messaging channel - Upload it to Paperarchive via `POST /v1/documents` - Paperarchive processes the image through OCR and AI analysis - Your assistant confirms the upload with the detected title and category ### Search Documents Try asking: "Find all invoices from Deutsche Telekom" ``` // OpenClaw makes this API call: POST https://api.paperarchive.io/v1/search { "query": "invoices Deutsche Telekom", "limit": 10 } ``` The assistant returns a list of matching documents with titles and dates. ### Ask Questions About Your Documents Try: "What was the total on my electricity bill from last month?" OpenClaw will search for the document, retrieve its OCR text, extract the relevant information, and provide a clear answer. ## Advanced Use Cases ### Automated Receipt Archival Set up a dedicated WhatsApp group or Telegram channel where you forward all receipts. OpenClaw watches the channel and uploads every image to Paperarchive automatically - no interaction needed. ### Scheduled Document Reports Use OpenClaw's cron functionality to generate a weekly summary of uploaded documents: ``` { "cron": { "weekly_document_report": { "schedule": "0 9 * * 1", "prompt": "List all documents uploaded in the last 7 days from Paperarchive and send me a summary on WhatsApp with the count per category." } } } ``` ### Smart Document Routing Teach OpenClaw to route documents to specific Paperarchive spaces based on content. For example, any document mentioning "tax" goes to the "Tax 2026" space, while invoices go to the "Business" space. ### Multi-User Setup for Families Run OpenClaw with multiple messaging connections so each family member can upload and search documents independently, all flowing into the same Paperarchive account with different spaces. ### Webhook-Triggered Processing Use OpenClaw's webhook endpoints to trigger document workflows from other systems: ``` curl -X POST http://localhost:3838/hooks/agent \ -H "Authorization: Bearer your-openclaw-token" \ -H "Content-Type: application/json" \ -d '{ "message": "Search Paperarchive for all unpaid invoices and send me a summary on Telegram", "agentId": "main" }' ``` ## Security Best Practices - Use minimum scopes: If your assistant only needs to search and read documents, create an API key with just `documents:read` and `search` scopes. - Restrict to specific spaces: Limit the API key to only the spaces your assistant should access. - Run OpenClaw locally: Keep sensitive document data on your own hardware rather than in the cloud. - Rotate API keys: Periodically generate a new Paperarchive API key and update your OpenClaw configuration. - Use OpenClaw's sandboxed mode: Enable sandboxing if you want to restrict OpenClaw's system access while still allowing API calls. ## Troubleshooting | Issue | Solution | | --- | --- | | OpenClaw does not call the Paperarchive API | Verify the skill file is loaded by checking the OpenClaw dashboard. Restart OpenClaw after adding the skill. | | "Invalid or missing API key" error | Check that the environment variable `PAPERARCHIVE_API_KEY` is set and starts with `pa_live_`. | | File upload fails | Ensure the file is under 50 MB. Paperarchive accepts PDF, JPEG, PNG, TIFF, and Office documents (DOCX, XLSX, PPTX, ODT and more). | | Search returns no results | Confirm that documents exist in the spaces accessible by your API key. Try broader search terms. | | Messages not arriving from WhatsApp/Telegram | Check the messaging channel configuration in the OpenClaw dashboard and verify the bot token is correct. | ## Frequently Asked Questions ### Is OpenClaw free to use? Yes, OpenClaw is fully open-source and free. You only pay for the LLM provider you choose (Anthropic, OpenAI, or free with local models via Ollama) and your Paperarchive subscription. ### Can I use this integration with a local AI model? Absolutely. OpenClaw supports local models through Ollama, so the entire stack - OpenClaw, your LLM, and document processing - can run on your own hardware. Only the Paperarchive API calls go to the cloud. ### How does this differ from using the Paperarchive app directly? The app provides a full visual interface for managing documents. The OpenClaw integration adds a conversational layer - ideal for quick uploads from your phone, hands-free document lookups, and automated workflows that run without your input. ### Can multiple people use the same assistant? Yes. OpenClaw supports multi-channel setups, so you can connect WhatsApp for yourself and Telegram for a family member, all linked to the same Paperarchive account. Use separate spaces to keep documents organized per person. ### What happens to my data? OpenClaw runs on your machine and your documents are stored in Paperarchive (hosted in Germany, GDPR-compliant). No document data passes through OpenClaw's servers - the project is fully open-source and runs locally. ## Next Steps - Read the [Authentication guide](https://paperarchive.io/docs/api/authentication) for more on API key scopes and security - Explore the [Documents API](https://paperarchive.io/docs/api/documents) for all available endpoints - Try the [Search API](https://paperarchive.io/docs/api/search) to build powerful document queries - Check out the [n8n integration guide](https://paperarchive.io/docs/api/n8n-quickstart) if you want to build visual automation workflows - Visit the [OpenClaw GitHub repository](https://github.com/openclaw/openclaw) for the latest documentation and community skills --- ## n8n Integration URL: https://paperarchive.io/docs/api/n8n-quickstart Learn how to integrate Paperarchive with n8n to automate document workflows - process invoices from email, sync with accounting tools, back up documents, and build powerful no-code document processing pipelines. # n8n + Paperarchive: Automate Your Document Workflows [n8n](https://n8n.io/) is a powerful open-source workflow automation platform that connects hundreds of apps and services through a visual, node-based editor. By integrating n8n with the Paperarchive API, you can build automated document processing pipelines that run 24/7 without writing code - from email-to-archive workflows to accounting integrations and AI-powered document analysis. This guide walks you through the complete setup: installing n8n, configuring Paperarchive credentials, building your first automation workflow, and exploring advanced use cases for document management automation. ## Why Combine n8n with Paperarchive? Paperarchive provides AI-powered document storage with automatic OCR, categorization, and full-text search. n8n adds the automation layer that connects Paperarchive to the rest of your digital ecosystem: - Email-to-Archive: Automatically extract PDF attachments from incoming emails and upload them to Paperarchive for instant processing and categorization. - Accounting Sync: When Paperarchive categorizes a document as an invoice, forward the extracted data (amount, date, sender) to your accounting tool like Lexoffice, sevDesk, or QuickBooks. - Cloud Storage Backup: Watch a Google Drive or Dropbox folder for new files and automatically archive them in Paperarchive with AI-powered metadata extraction. - Notification Pipelines: Get a Slack or email notification when specific types of documents are uploaded, such as contracts nearing expiry or tax-relevant invoices. - Batch Processing: Upload hundreds of documents from a folder, CSV file, or API endpoint in a single automated run. ## Prerequisites Before you start, you will need: - A Paperarchive account with an active subscription. [Sign up free](https://app.paperarchive.io/register) if you do not have one yet. - A Paperarchive API key. Create one at [Settings > API Keys](https://app.paperarchive.io/settings#api-keys). For automation workflows, recommended scopes are: `documents:read`, `documents:write`, `search`, `spaces:read`, `categories:read`, `tags:read`, `senders:read`. - An n8n instance - either self-hosted or [n8n Cloud](https://n8n.io/cloud/). ## Step 1: Set Up n8n If you do not have n8n running yet, here are the quickest ways to get started: ### n8n Cloud (Fastest) Sign up at [n8n.io/cloud](https://n8n.io/cloud/) for a hosted instance with no setup required. A free trial is available. ### Docker (Self-Hosted) ``` docker run -d --name n8n \ -p 5678:5678 \ -v n8n-data:/home/node/.n8n \ n8nio/n8n ``` Open `http://localhost:5678` to access the n8n editor. ### npm (Self-Hosted) ``` npm install -g n8n n8n start ``` ## Step 2: Add Paperarchive Credentials in n8n In the n8n editor, you need to set up Paperarchive as a custom API credential so all your workflows can authenticate securely. - Open the n8n editor and go to Settings > Credentials - Click Add Credential and choose Header Auth - Configure the credential: Name: Paperarchive API - Header Name: Authorization - Header Value: Bearer pa_live_your_key_here - Click Save This credential will be available in all HTTP Request nodes throughout your workflows. ## Step 3: Build Your First Workflow - Email to Archive The most popular Paperarchive automation is the email-to-archive pipeline. Here is how to build it step by step: ### Workflow Overview This workflow watches your email inbox, detects messages with PDF attachments, uploads each attachment to Paperarchive, and sends you a confirmation notification. ### Node 1: Email Trigger Add an IMAP Email trigger node and configure it with your email credentials. Set it to check for new emails every few minutes. Enable Download Attachments to capture file data. ### Node 2: Filter Attachments Add an IF node to check if the email contains attachments. Set the condition to: `{{ $json.attachments.length > 0 }}` ### Node 3: Upload to Paperarchive Add an HTTP Request node with these settings: ``` Method: POST URL: https://api.paperarchive.io/v1/documents Authentication: Header Auth (select your Paperarchive API credential) Content-Type: multipart/form-data Body Parameters: - file: {{ $binary.attachment_0 }} - space_id: your-space-uuid (optional) ``` ### Node 4: Confirmation Add a Slack, Email, or Telegram node to send yourself a notification: ``` "New document archived: {{ $json.data.name }} - Processing started." ``` Activate the workflow and every email with a PDF attachment will now flow directly into your Paperarchive account. ## Step 4: Add Search and Retrieval Workflows Beyond uploading, n8n can automate document searches and data retrieval from Paperarchive. ### Webhook-Triggered Document Search Build a workflow that exposes a webhook endpoint for searching your document archive: ``` // Webhook node receives: POST https://your-n8n-instance.com/webhook/paperarchive-search { "query": "electricity bill January 2026" } // HTTP Request node calls: POST https://api.paperarchive.io/v1/search Headers: Authorization: Bearer pa_live_your_key Body: { "query": "electricity bill January 2026", "limit": 5 } // Response is returned to the webhook caller ``` This turns your Paperarchive into an API-accessible search service that any other tool or automation can query. ## Real-World Automation Recipes ### Recipe 1: Invoice Processing Pipeline Automatically process incoming invoices end-to-end: - Trigger: Email arrives with an invoice attachment - Upload: n8n sends the PDF to `POST /v1/documents` - Wait: Delay 30 seconds for Paperarchive to finish OCR and AI analysis - Retrieve: Fetch the processed document via `GET /v1/documents/:id` - Extract: Read the extracted amount, currency, and structured_data (line items, tax breakdown) directly from the response - Sync: Send the extracted data to your accounting tool (Lexoffice, sevDesk, Xero) - Notify: Post a summary to your Slack channel ``` // After document processing completes, the response includes: { "data": { "title": "Invoice #2026-0142", "event_type": "invoice", "amount": 29.99, "currency": "EUR", "structured_data": { "line_items": [ ... ], "tax_breakdown": { ... } }, "ocr_text": "Invoice #2026-0142\nDate: March 7, 2026\n...", "category_id": "invoices-category-uuid" } } ``` ### Recipe 2: Google Drive to Paperarchive Sync Automatically archive files dropped into a Google Drive folder: - Trigger: Google Drive trigger watches a "To Archive" folder - Download: Download the new file from Google Drive - Upload: Send the file to Paperarchive via the API - Move: Move the original file to an "Archived" folder in Google Drive - Log: Add a row to a Google Sheet with the document ID and timestamp This creates a seamless drop-and-forget workflow: put files in a folder on your phone or desktop, and they are automatically processed and archived. ### Recipe 3: Weekly Document Digest Get a weekly summary of all new documents in your archive: - Trigger: Cron node fires every Monday at 9 AM - Fetch: Call `GET /v1/documents?sort_by=created_at&sort_order=desc&limit=50` - Filter: Filter for documents created in the last 7 days - Group: Group documents by category - Format: Build a formatted HTML email with document counts per category - Send: Email the digest to yourself ### Recipe 4: Scan Folder Watcher If you use a network scanner (e.g. Brother, Fujitsu ScanSnap), set up a workflow that watches the scan output folder and uploads new files: - Trigger: Local File trigger watches `/scans/` folder - Upload: Send each new PDF to `POST /v1/documents` - Archive: Move the scanned file to a `/processed/` folder Combined with Paperarchive's automatic AI categorization, this creates a fully hands-free scanning-to-archive pipeline. ### Recipe 5: Document Expiry Alerts Monitor for contracts or documents that are about to expire: - Trigger: Daily cron at 8 AM - Search: Call `POST /v1/search` with query "contract" or "expires" - Retrieve: Get full document details and check `document_date` - Filter: Find documents expiring within the next 30 days - Alert: Send a notification via email, Slack, or push notification ## Working with the Paperarchive API in n8n ### HTTP Request Node Configuration All Paperarchive API calls use the HTTP Request node with these common settings: | Setting | Value | | --- | --- | | Base URL | `https://api.paperarchive.io/v1` | | Authentication | Header Auth (Paperarchive API credential) | | Content-Type (JSON) | `application/json` | | Content-Type (Upload) | `multipart/form-data` | ### Handling Pagination When listing documents, use pagination to process large archives: ``` // First request GET /v1/documents?limit=50&offset=0 // Use the 'total' field from the response to loop // Next request GET /v1/documents?limit=50&offset=50 // Continue until offset >= total ``` In n8n, use a Loop Over Items node or SplitInBatches node to process paginated results. ### Waiting for Document Processing After uploading a document, Paperarchive processes it asynchronously (OCR, AI analysis). If your workflow needs the processed data, add a Wait node (15-60 seconds depending on document complexity) before retrieving the document details: ``` 1. POST /v1/documents → Upload, get document ID 2. Wait 30 seconds → Allow processing to complete 3. GET /v1/documents/:id → Retrieve with OCR text and structured data ``` ### Error Handling Use n8n's built-in error handling to manage API failures gracefully: - Add an Error Trigger node to catch workflow failures and send alerts - Use IF nodes to check for `success: false` in API responses - Implement retry logic for `429 Too Many Requests` errors with a Wait node - Log errors to a Google Sheet or database for debugging ## Scaling Your Automation ### Rate Limiting The Paperarchive API allows 60 requests per minute per API key, and document uploads are limited to 10 per minute. When processing large batches: - Use n8n's SplitInBatches node to process 10 documents at a time - Add a Wait node (60+ seconds) between upload batches to stay under the 10 uploads/minute limit - Monitor the `RateLimit-Remaining` header in responses ### Multiple Workflows Create separate workflows for different automation tasks rather than one monolithic workflow. This makes debugging easier and allows you to activate/deactivate individual automations. ### Credential Management For production setups, create separate Paperarchive API keys for each workflow so you can revoke access to specific automations without affecting others. ## Security Considerations - Use minimum scopes: Create API keys with only the scopes each workflow needs. A read-only reporting workflow should not have `documents:write` access. - Restrict spaces: If a workflow only processes documents in a specific space, restrict the API key to that space. - Secure your n8n instance: Use HTTPS, strong passwords, and restrict network access to your n8n editor. - Rotate API keys: Periodically rotate Paperarchive API keys used in automated workflows. - Audit workflows: Regularly review active workflows to ensure they are still needed and functioning correctly. ## Troubleshooting | Issue | Solution | | --- | --- | | HTTP Request returns 401 | Verify your Header Auth credential has the correct API key with the `Bearer ` prefix (note the space). | | File upload fails with 400 | Ensure you are sending as `multipart/form-data` with the file in a field named `file`. Supported formats: PDF, JPEG, PNG, TIFF, and Office documents (DOCX, XLSX, PPTX, ODT and more). | | Document has no OCR text after upload | Processing is asynchronous. Add a Wait node (30+ seconds) before retrieving the document details. | | Rate limit errors (429) | Add delays between requests using Wait nodes. Use SplitInBatches for bulk operations. | | Workflow does not trigger | Check that the workflow is activated (toggle in the top right). For email triggers, verify IMAP credentials and polling interval. | | Binary data issues | When downloading files from other services, use the `{{ $binary }}` expression to reference binary data in the HTTP Request body. | ## Frequently Asked Questions ### Is n8n free to use? n8n is open-source and free to self-host. n8n Cloud offers paid hosted plans with a free trial. Both options work with the Paperarchive API. ### Do I need coding skills to use n8n with Paperarchive? No. n8n's visual editor lets you build complete automation workflows by connecting nodes and configuring settings - no code required. For advanced use cases, you can add JavaScript expressions and code nodes. ### How many documents can I process automatically? There is no hard limit on the n8n side. Paperarchive's upload rate limit of 10 uploads per minute means you can archive roughly 600 documents per hour. For large batch imports, use pagination and delays to stay within limits. ### Can I trigger n8n workflows from Paperarchive? Yes. Create a webhook-triggered workflow in n8n and call that webhook URL from any system that supports outbound HTTP requests. This enables bi-directional integration. ### Which n8n version do I need? Any current version of n8n (1.x or later) supports HTTP Request nodes with Header Auth, which is all you need for the Paperarchive integration. No custom n8n nodes are required. ### Can I use this with n8n Cloud? Absolutely. The Paperarchive API is a public REST API accessible from any n8n instance, whether self-hosted or cloud-based. ## Next Steps - Read the [Authentication guide](https://paperarchive.io/docs/api/authentication) for more on API key scopes and restrictions - Explore the [Documents API](https://paperarchive.io/docs/api/documents) to see all available document operations - Try the [Search API](https://paperarchive.io/docs/api/search) for building search-powered automations - Check out the [OpenClaw integration guide](https://paperarchive.io/docs/api/openclaw-quickstart) for conversational document management - Browse [n8n's workflow templates](https://n8n.io/workflows/) for inspiration on building document automations - Visit the [API Playground](https://paperarchive.io/docs/api/playground) to test endpoints interactively --- ## MCP Connector URL: https://paperarchive.io/docs/api/mcp-connector Connect Paperarchive to AI assistants via the Model Context Protocol. General server reference plus setup guides for Claude, ChatGPT, and Grok. # MCP Connector Paperarchive ships a remote [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server. Once connected, an AI assistant such as Claude, ChatGPT, or Grok can search your archive, read document details, look up bank statement transactions, and hand you download links - directly from a conversation. ## Endpoint ``` https://api.paperarchive.io/mcp ``` The server speaks MCP over Streamable HTTP and authenticates via OAuth 2.1. Any MCP client that supports remote servers with OAuth can connect. Authorization happens in the Paperarchive app: you log in, review the requested permissions, choose which Spaces the connection may access, and approve. The connection is strictly read-only - MCP clients cannot create, change, or delete anything in your archive. ## Requirements - A Paperarchive account with an active Premium or trial plan (same requirement as API keys). - An MCP client that supports remote servers, for example Claude, ChatGPT, or Grok (see the setup guides below). ## Available tools | Tool | Scope | Description | | --- | --- | --- | | `search_documents` | `search` | Full-text search across titles, senders, categories, tags, and OCR text. | | `list_documents` | `documents:read` | Browse documents with filters (space, category, status, date) and pagination. | | `get_document` | `documents:read` | Document details incl. extracted fields, tags, and optionally OCR text. | | `get_document_download_link` | `documents:read` | Short-lived signed URL (10 minutes) for the original file. | | `list_statements` | `documents:read` | Bank statements with extracted structured data. | | `get_statement_transactions` | `documents:read` | Transactions, balances, IBAN, and period of a statement. | | `list_events` | `events:read` | Events (invoices, contracts, policies, ...) with state, amount, and due date - answers questions like "What is open or due?". | | `get_event` | `events:read` | Details of a single event incl. amounts, deadlines, reference number, and source document. | | `list_spaces` | `spaces:read` | Spaces the connection can access. | | `list_categories` | `categories:read` | Categories for filtering documents. | | `list_tags` | `tags:read` | Tags in the accessible Spaces. | | `list_senders` | `senders:read` | Detected senders in the accessible Spaces. | Only tools covered by the granted scopes appear in the client. All results are filtered to the Spaces selected during authorization. ## How authorization works - OAuth 2.1 with PKCE (S256): clients register dynamically (RFC 7591); only public clients with PKCE are accepted. Discovery lives at `/.well-known/oauth-authorization-server` and `/.well-known/oauth-protected-resource`. - Read-only scopes: the connector can request `documents:read`, `search`, `events:read`, `spaces:read`, `categories:read`, `tags:read`, and `senders:read`. Write scopes are not available over MCP. - Tokens: access tokens expire after 1 hour; refresh tokens rotate on every use and expire after 30 days of inactivity. Tokens are stored hashed. - Space restriction: the Spaces you select at approval time are a hard server-side filter for every tool call. - API keys as an alternative: clients without OAuth support can send a Paperarchive API key as a Bearer token in the `Authorization` header. The key's scopes and Space restrictions apply exactly as documented under [Authentication](https://paperarchive.io/docs/api/authentication). ## Managing and revoking access Connected apps are listed in the Paperarchive app under Settings > API Keys > Connected Apps. Disconnecting an app immediately invalidates all of its tokens. Access also ends automatically when your Premium plan lapses. ## Client setup The connection flow is the same everywhere: add `https://api.paperarchive.io/mcp` as a custom connector, get redirected to Paperarchive, log in, pick your Spaces, and click Allow access. Only the menu paths differ per client. ### Claude (claude.ai and Claude Desktop) - Open Settings > Connectors (Team/Enterprise: an admin does this under organization settings). Custom connectors require a paid plan (Pro, Max, Team, or Enterprise). - Click Add custom connector, enter the endpoint URL, and confirm. - Complete the Paperarchive approval flow, then enable the connector in a chat via the tools menu. ### Claude Code ``` claude mcp add --transport http paperarchive https://api.paperarchive.io/mcp ``` Claude Code opens the authorization flow in your browser on first use. Alternatively, authenticate with a Paperarchive API key instead of OAuth: ``` claude mcp add --transport http paperarchive https://api.paperarchive.io/mcp \ --header "Authorization: Bearer pa_live_YOUR_KEY" ``` ### ChatGPT - Available on paid plans (Plus, Pro, Business, Enterprise, Edu) in the web app. - Enable Developer mode: Settings > Apps > Advanced settings (the toggle has also lived under Settings > Connectors > Advanced - the location varies by rollout). - Add a new connector with the endpoint URL. ChatGPT supports Streamable HTTP with OAuth, so the standard approval flow runs. - Enable the connector in a conversation to use the Paperarchive tools. ### Grok - Open [grok.com/connectors](https://grok.com/connectors) and click New Connector. - Select Custom, enter the endpoint URL, and complete the Paperarchive approval flow. - Grok discovers the tools automatically and makes them available in conversations. ### Other MCP clients Any MCP client that supports remote Streamable HTTP servers works. With OAuth support, the standard approval flow runs; without it, use a Paperarchive API key in the `Authorization` header as described above. ## Troubleshooting - The client asks to re-authenticate: the refresh token expired or the connection was revoked. Re-run the connect flow. - Tools are missing: the corresponding scope was not granted. Disconnect and reconnect with the needed permissions. - 403 or "Premium feature": the connector requires an active Premium or trial plan. - 429 responses: the connector shares the public API rate limit of 60 requests per minute per connection. --- ## Errors & Rate Limits URL: https://paperarchive.io/docs/api/errors Error response format, HTTP status codes, validation messages, and rate-limit headers returned by the Paperarchive API across every endpoint in this reference. # Errors & Rate Limits ## Error Format All error responses follow a consistent format: ``` { "success": false, "error": "Description of the error" } ``` ## HTTP Status Codes | Code | Meaning | | --- | --- | | `200` | Success - request completed. | | `201` | Created - resource was created successfully. | | `202` | Accepted - file uploaded, document record will appear shortly. | | `400` | Bad Request - missing or invalid parameters, unsupported file type, or Content-Type mismatch. | | `401` | Unauthorized - missing or invalid API key. | | `403` | Forbidden - API key lacks required scope or space access. | | `404` | Not Found - resource does not exist or is not accessible. | | `413` | Payload Too Large - uploaded file exceeds the 50 MB limit. | | `429` | Too Many Requests - rate limit exceeded (60 requests per minute per API key; document uploads are limited to 10 per minute). | | `500` | Internal Server Error - something went wrong on our end. | Note on duplicates: uploading a file that already exists in your library is not rejected with an error. The upload is accepted and the document finishes processing with status `skipped`. ## Rate Limits API requests are rate-limited to ensure fair usage: - 60 requests per minute per API key - 10 document uploads per minute (POST /v1/documents) Rate limit information is included in every response using the standard `RateLimit-*` headers: ``` RateLimit-Limit: 60 RateLimit-Remaining: 55 RateLimit-Reset: 42 ``` `RateLimit-Reset` is the number of seconds until the current window resets. A `429` response additionally includes a `Retry-After` header (seconds) and a `retryAfter` field in the JSON body. ## Handling Rate Limits When you receive a `429` response, wait for the number of seconds indicated by the `Retry-After` header before retrying. Implement exponential backoff for robustness: ``` async function fetchWithRetry(url, options, maxRetries = 3) { for (let i = 0; i setTimeout(r, Math.max(retryAfter * 1000, 1000))); continue; } return response; } throw new Error("Rate limit exceeded after retries"); } ``` ## Common Error Scenarios | Error | Cause | Solution | | --- | --- | --- | | "Invalid or missing API key" | Missing `Authorization` header or malformed key. | Check your API key format and header. | | "Insufficient scope" | API key doesn't have the required scope. | Update key scopes in Settings > API Keys. | | "Access denied to this space" | API key is restricted and can't access the requested space. | Add the space to the key's allowed spaces or use a key with broader access. | | "Document not found" | Document doesn't exist or is in an inaccessible space. | Verify the document ID and your key's space access. | | "File content does not match any supported format" | Uploaded file bytes don't match PDF, JPEG, PNG, TIFF, or Office document signatures. | Ensure you're uploading a valid file in a supported format. | | "Content-Type mismatch" | The Content-Type header doesn't match the actual file content. | Set the correct Content-Type for your file or let your HTTP client detect it. | --- ## Playground URL: https://paperarchive.io/docs/api/playground Interactive playground for the Paperarchive REST API. Test endpoints with your own API key, inspect responses live, and copy ready-to-paste curl examples.