Skip to content
TrompTech
LayerWebsitesCustom softwareProductsOur work
EN
NederlandsEnglishFrançaisDeutschEspañol
Log inBook a call
LayerWebsitesCustom softwareProductsOur workKnowledge & practiceContact
Book a callLog in
NLENEnglishFRDEES
Home / Developers

TROMPTECH LAYER

Developers

Connect your own software and AI apps to the Layer. Reading happens directly, within the permissions you give. A change always becomes a proposal that a person approves first.

Last updated: 2 October 2026

There are three ways to work with the Layer from outside:

  • Connect an AI app via MCP, such as Claude or ChatGPT. You sign in to the Layer and choose what the app may do.
  • The REST API for your own software, with a key you create yourself.
  • Webhooks: the Layer notifies your address that something happened, such as a paid invoice.

1. How it stays safe

  • Never more than the creator. A key or connected app can never do more than the person who created it. If their role changes, the key changes with it. If someone leaves the team, their key stops working.
  • Writing is always a proposal. Nothing from outside changes anything in your workspace by itself. Every change goes to Approvals and only happens once someone with that permission approves it.
  • Text from outside stays marked. What comes in via the API or MCP counts as text from outside. A proposal with such text never goes through automatically, even if you let other proposals run automatically.
  • Visible and revocable. Under Settings, Devices you see every key and app, when it was last used and what it did. Revoking takes effect immediately.
  • A brake. Each key and app may make 120 requests per minute. Above that you get a 429 with a Retry-After.

2. Creating a key

In the Layer: Settings, Developers, API key. Give the key a name, choose how long it is valid (30 days, 90 days or a year) and tick what it may do. You see the key once. We only store a hash, so lost is lost: revoke it and create a new one.

Keys belong to your own workspace, not to the demo. The exact address of your API and MCP server is on the same page; the examples below use https://jouw-werkplek.example.

PermissionWhat it grants
relaties.lezenCustomers, leads, suppliers and their contacts.
offertes.lezenQuotes with their lines and status.
facturen.lezenInvoices with amounts, status and payment date.
leads.lezenLeads with stage, value and next action. With Make proposals, also create and update leads.
communicatie.lezenThe timeline of calls, emails, conversations and notes per relation. With Make proposals, also log them.
mail.lezenSearch and read the mailboxes you see in the Layer yourself, with per conversation who wrote last and whether there is already a reply. Read only, without attachments. What the app reads goes to the AI you connect.
agenda.lezenYour own appointments. With Make proposals, also schedule an appointment, without an invitation.
facturen.conceptCreate a draft invoice (from open hours or with your own lines) or an open invoice with a link for the customer, edit it and view the PDF. Sending is always a proposal in Approvals; you share the link yourself.
offertes.conceptA new quote as a draft. You always send it yourself in the Layer.
bedrijf.vragenSearches meeting notes, the knowledge base, customers, tasks and records for the pieces that match a question, with the source.
projecten.lezenProjects with status, deadline and tasks.
taken.lezenTasks with status, deadline and priority.
uren.lezenLogged hours. Amounts only if your role may see money.
producten.lezenProducts and services with price and stock.
tickets.lezenSupport tickets with status and priority.
content.lezenPosts in the content calendar with channel, date and status.
series.lezenFormats, series and episodes with their stage and verdict.
radar.lezenIdeas with score and signals from the radar: outliers, channel growth, search queries.
social.lezenFollowers and standard figures per own social account per day.
analytics.lezenVisitors and search traffic from Google Analytics and Search Console.
radar.sturenTurn discovery on or off, steer search terms and channels and start the trend analyst. Only for whoever manages the radar in the workspace.
radar.feedbackMark ideas from the radar as good or not good. That only steers where the radar searches and what the trend analyst makes; nothing goes out.
content.voorstellenPropose a post as an idea in the content calendar. Together with Make proposals; it waits in Approvals.
verslagen.insturenPut reports from TrompTech Notulen into Meetings. What happens with them (tasks, contact moment, email) you choose yourself afterwards.
verslagen.verwerkenFrom a report you sent in yourself, create tasks, a contact moment and a draft email, like the Process button in Meetings. Only what your role allows; an email is never sent.
opnames.insturenPut inspections, handovers and damage reports from TrompTech Opname on the PC into Inspections, with the photos and the report.
opnames.lezenYour inspections with their points and photos, to finish on the PC an inspection that started on the phone.
uren.schrijvenPut what TrompTech Uren saw on your PC and you checked into your own timesheet as a draft, and read your own hours so nothing is logged twice. You submit it yourself; window titles are not included.
gids.lezenWhich pages and help articles you can open in this workspace, for TrompTech Gids on your PC: it answers questions about the Layer and takes you to the right place. No data about customers or colleagues.
content.insturenPut carousels from TrompTech Slides and videos and shorts from TrompTech Studio into the content calendar as a post, with the images or the video. They wait for your approval; you publish them yourself.
dictaat.insturenPut what you dictate in TrompTech Voice into the Outbox as a task, as an internal note with a customer or as an email draft. Only what your role allows; an email is never sent.
documenten.delenShare proposals and reports from TrompTech Documenten with a customer as a web page, see when they open them, and store the PDF with the customer and the project.
kennis.insturenPut instruction videos with steps from TrompTech Uitleg into the knowledge base.
afletteren.transacties.schrijvenPut credits from an account into reconciliation, for a personal account that is also used for business. Reading is not possible with this permission.
huishouden.lezenYour household budget (income, fixed costs, budgets and debts), your shopping list and your tasks. Read only, no advice.
huishouden.schrijvenAdd groceries to the list, tick them off and remove them, and add and tick off household tasks: directly, with Undo. A debt or budget always remains a proposal in Approvals. Also reads your household.
aanbiedingen.lezenThe supermarket offers for this week and next from your offers app, and compare prices per shop for your groceries. Read only.
voorstellen.makenPropose changes. They wait in Approvals until someone approves them; nothing happens on its own.

A permission only works if the module is in your subscription and your role allows it. Amounts, such as an hourly rate, are only visible if your role may see money.

3. The REST API

Everything is under /api/v1. Send the key as Authorization: Bearer. GET /api/v1 shows which resources your key can read. The full description is in /api/v1/openapi.json (OpenAPI 3.1), which you can also fetch without a key.

Reading and paging

curl "https://jouw-werkplek.example/api/v1/taken?status=open&per_pagina=20" \
  -H "Authorization: Bearer $LAYER_SLEUTEL"

Every list comes in pages, newest first. Use per_pagina (1 to 100, default 50) and pagina to page through; volgende gives the address of the next page, or null. Filter with status, or with sinds (a date or time in ISO 8601) to fetch only what has changed since then.

{
  "data": [ { "id": "...", "titel": "...", "status": "open", "deadline": "2026-10-03T07:00:00.000Z" } ],
  "pagina": 1,
  "per_pagina": 20,
  "totaal": 1,
  "volgende": null
}
ResourcePermissionProposals
/api/v1/relaties
Customers, leads and (with the Suppliers module) suppliers.
relaties.lezennew (POST): soort, naam, bedrijf, email, telefoon, adres, postcode, plaats, kvk, btw, branche, rechtsvorm, notities, bron; change (PATCH): telefoon, branche, rechtsvorm, plaats, website, bron
/api/v1/contactpersonen
Contacts at a customer, lead or supplier.
relaties.lezennew (POST): naam, bedrijf, email, telefoon, notities, bron
/api/v1/offertes
Quotes with lines, amount and status.
offertes.lezenchange (PATCH): status
/api/v1/facturen
Invoices with lines, amount, status and payment date.
facturen.lezenchange (PATCH): status, betaald_op
/api/v1/projecten
Projects with status, deadline, tasks and progress.
projecten.lezenchange (PATCH): status, deadline
/api/v1/taken
Tasks with status, deadline and priority.
taken.lezennew (POST): titel, omschrijving, deadline, prioriteit, klant_id, project_id; change (PATCH): status, deadline, prioriteit
/api/v1/uren
Logged hours: your own, or those of the whole team if your role may see that. Rate and invoice only if your role may see that.
uren.lezenread only
/api/v1/producten
Products and services with price and stock. The purchase price only if your role may see money.
producten.lezenread only
/api/v1/tickets
Support tickets with status, priority and category.
tickets.lezenchange (PATCH): status
/api/v1/content
Posts in the content calendar: date, channel, topic, status and the series they belong to.
content.lezenread only
/api/v1/formats
Formats: the fixed structure of an episode, the form and length per platform, and the checklist.
series.lezenread only
/api/v1/series
Series: a format with cadence, account and status.
series.lezenread only
/api/v1/afleveringen
Episodes of all series, with date, stage, script and verdict.
series.lezenread only
/api/v1/radar-ideeen
Ideas with a score from the content radar. The score is a band with components, never a chance of going viral.
radar.lezenread only
/api/v1/radar-serievoorstellen
Series suggestions from the trend analyst: a recurring show on a topic that comes back across several outliers. You create a series in the Layer itself.
radar.lezenread only
/api/v1/radar-signalen
Signals from the last 90 days: outliers, early outliers, channel growth, search queries and news, with an explanation of how they were calculated.
radar.lezenread only
/api/v1/social-metingen
Per own social account per day, the followers and the standard figures the channel reports (last 120 days). A missing figure is null, never zero.
social.lezenread only

Proposing a change

With the permission voorstellen.maken you propose a new record or a change. The response is a 202: the proposal is ready, nothing has changed yet. Explain why in waarom, so the reviewer sees it alongside.

curl -X POST "https://jouw-werkplek.example/api/v1/taken" \
  -H "Authorization: Bearer $LAYER_SLEUTEL" \
  -H "Content-Type: application/json" \
  -d '{"titel": "Follow up on the quote", "deadline": "2026-10-03", "waarom": "Agreed in the meeting"}'
HTTP/1.1 202 Accepted

{
  "voorstel": { "id": "...", "actie": "taak.nieuw", "titel": "...", "status": "wacht", "link": "https://jouw-werkplek.example/app/ai/goedkeuringen?id=..." },
  "uitleg": "Dit is een voorstel. Er is nog niets veranderd: het wacht in Goedkeuringen tot iemand het goedkeurt."
}

Follow the status with GET /api/v1/voorstellen or GET /api/v1/voorstellen/{id}; you only see the proposals of your own key. If you prefer a webhook, subscribe to voorstel.goedgekeurd. Other actions the AI in the Layer knows, you propose with POST /api/v1/voorstellen and {"actie": "...", "gegevens": { ... }}. If an action is not possible, or something is missing, you get a 422 with the reason. Deleting is not possible via the API.

Errors

An error is always JSON: {"fout": {"code": "...", "melding": "..."}}, with a message in plain language.

CodeMeaning
400The request is not valid, for example an invalid date or a missing field.
401No key, or a key that has expired or been revoked.
403The key is missing a permission. The WWW-Authenticate header names which permission.
404This address or record does not exist, or you are not allowed to see it.
405This method is not possible here. The Allow header names what is.
422The proposal was rejected, with the reason.
429Too many requests. Wait the number of seconds from Retry-After.

4. Webhooks

Whoever manages integrations in the Layer sets up webhooks under Settings, Developers, Webhooks: an address and the events you want to hear about. You see the secret for checking the signature once.

EventWhen
factuur.verstuurdAn invoice is set to sent.
factuur.betaaldAn invoice is set to paid.
offerte.geaccepteerdA customer accepted a quote.
ticket.nieuwA new support ticket has come in, including from an email.
taak.afgerondSomeone completed a task.
voorstel.goedgekeurdA proposal in Approvals has been approved.

A message is deliberately thin: what happened and where you can read it, no amounts or customer data. You fetch the content with a key, via href. The id stays the same if we resend a message, so you can use it to recognise a duplicate.

POST /jouw-webhook HTTP/1.1
Content-Type: application/json
TrompTech-Event: factuur.betaald
TrompTech-Delivery: ...
TrompTech-Signature: t=1790931600,v1=...

{
  "id": "evt_...",
  "type": "factuur.betaald",
  "aangemaakt": "2026-10-02T09:00:00.000Z",
  "data": { "object": "factuur", "id": "...", "nummer": "...", "href": "/api/v1/facturen/..." }
}

Checking the signature

The TrompTech-Signature header contains a time t (in seconds) and v1: an HMAC-SHA256 with your secret over t, a dot and the body as it arrived. Compute it yourself, compare in constant time and reject messages older than five minutes.

import { createHmac, timingSafeEqual } from "node:crypto";

// geheim: the full webhook secret, including the whsec_ prefix.
// inhoud: the body exactly as it arrived, as text (do not parse it as JSON first).
export function handtekeningKlopt(geheim, kop, inhoud) {
  const delen = new Map((kop ?? "").split(",").map(d => d.trim().split("=", 2)));
  const t = Number(delen.get("t")), v1 = delen.get("v1") ?? "";
  // Older than five minutes: reject, so nobody can replay an old message.
  if (!Number.isInteger(t) || Math.abs(Date.now() / 1000 - t) > 300 || !/^[0-9a-f]{64}$/.test(v1)) return false;
  const verwacht = createHmac("sha256", geheim).update(`${t}.${inhoud}`).digest();
  return timingSafeEqual(verwacht, Buffer.from(v1, "hex"));
}
import hashlib, hmac, re, time

def handtekening_klopt(geheim: str, kop: str, inhoud: bytes) -> bool:
    delen = dict(d.strip().split("=", 1) for d in (kop or "").split(",") if "=" in d)
    t, v1 = delen.get("t", ""), delen.get("v1", "")
    if not t.isdigit() or abs(time.time() - int(t)) > 300 or not re.fullmatch(r"[0-9a-f]{64}", v1):
        return False
    verwacht = hmac.new(geheim.encode(), t.encode() + b"." + inhoud, hashlib.sha256).hexdigest()
    return hmac.compare_digest(verwacht, v1)

Delivery and retries

  • Respond within 10 seconds with a 2xx. We do not follow a redirect (3xx).
  • If it fails, we try again after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours and 24 hours. After that the message counts as failed; you can resend it in the Layer.
  • If ten messages in a row fail, the webhook is switched off. You switch it back on yourself.
  • Only https to a public address by name, on the default port. An address that points to an internal network gets nothing; we check that again on every delivery.

5. Connecting an AI app via MCP

The Layer is an MCP server at https://jouw-werkplek.example/api/mcp (Streamable HTTP). Sign-in uses OAuth 2.1 with PKCE: the app sends you to the Layer, you sign in as usual (with your second factor if you have one) and choose on the consent screen what the app may do.

  • Claude: open Settings, Connectors, and add a custom connector with the address of your MCP server.
  • ChatGPT: open Settings, Apps & Connectors. Under Advanced, turn on developer mode and create a connector with the address, with OAuth as the sign-in.
  • Other apps: any MCP client with OAuth works. The Layer supports dynamic registration (RFC 7591) and Client ID Metadata Documents, and publishes its details at /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource.

The menu names in Claude and ChatGPT sometimes differ per version. The app only sees the tools that belong to the chosen permissions. Reading happens directly. Supported protocol versions: 2026-07-28, 2025-11-25, 2025-06-18 and 2025-03-26.

A plan first. The app makes a single change straight away. Several changes at once, or something that creates structure such as a project with tasks, it first records as a plan: exactly the actions with their data. You see that plan in your chat, and only after your explicit yes does the Layer carry out exactly those actions, once. Internal changes (a lead, contact moment, note, task, appointment without invitation, project or document) the Layer then carries out immediately, if your workspace allows it. You see them in Approvals and can undo them there. Anything that goes out or involves money, such as an email, an invitation, sending a quote or an invoice, always remains a proposal that you approve. A session via MCP always counts as text from outside.

A connected app keeps working until you revoke it under Settings, Devices, or until it has not been used for 30 days.

6. Questions or found a problem?

Email info@tromptech.nl. A security issue is better reported confidentially, as described under Report a security issue.

TrompTech

Software that works together.
Direct contact with the builder.

Baliëndijk 324
4816 GV Breda, Netherlands
+31 6 17720360info@tromptech.nl
NLENEnglishFRDEES

For your business

TrompTech LayerWebsites & online shopsCustom softwareAI chatbot (Breda)NL (in Dutch)ProductsKnowledge & practice

TrompTech

About TrompTechOur workContactCompany detailsComplaints & questionsStatus & incidents

Clearly arranged

Privacy statementCookie policyTerms and conditionsSubscriptions & direct debitAll documents & agreements →

© 2026 TrompTech · Jeremy Tromp · Sole proprietorship (eenmanszaak)

Chamber of Commerce no. 96345381 · VAT ID NL005203127B38

Ask TrompTech

Layer, websites & custom software

TrompTech

Hello, how can I help you? Ask a question about Layer, websites or custom software. Or try a product match below.

Fixed answers, no AI. A message goes to Jeremy · Privacy

Cookies

Necessary cookies keep the site working. If you also choose marketing, we use Google Analytics and Google Ads to measure which pages and adverts lead to enquiries, and we remember for 90 days which advert or link brought you here. For this, data about your visit is sent to Google. Personalised advertising is switched off. More information

Necessary cookies keep the site working. If you also choose marketing, we use Google Analytics and Ads to measure which adverts lead to enquiries, and data about your visit is sent to Google. More information