Developers

Keyio MCP server and API

Keyio has an MCP server: connect Claude, ChatGPT, Cursor, VS Code or any MCP-compatible assistant to your account and ask about your rentals, record expenses and invoices, log rent payments, open maintenance requests or prepare guest registration in plain language. Or use the REST API to integrate Keyio with your own tools. Included in every plan.

Not technical? See what you can do with your AI assistant →

Connect your AI assistant

Keyio is a remote MCP server (Streamable HTTP) with OAuth sign-in: the assistant works out how to authenticate by itself, you sign in to Keyio and choose what it may do. Nothing to install and no key to copy. The address is always the same:

https://gokeyio.com/api/mcp

Claude (web, Desktop and mobile)

  1. In Claude, open Customize → Connectors and click "Add custom connector".
  2. Name it "Keyio", paste the address above and click Add.
  3. Click Connect. Keyio opens: sign in, choose whether Claude can only read or also make changes, and click Allow.

On a Claude Team or Enterprise plan, an organization owner adds the connector once in Organization settings → Connectors, and each person clicks Connect with their own Keyio account.

Other assistants and editors

ChatGPT. With developer mode on (paid plans): Settings → Apps & Connectors → create a connector with Keyio’s address and OAuth authentication.

Claude Code. In the terminal, then /mcp to sign in:

claude mcp add --transport http keyio https://gokeyio.com/api/mcp

Cursor. In Settings → Tools & MCP, or in ~/.cursor/mcp.json:

{ "mcpServers": { "keyio": { "url": "https://gokeyio.com/api/mcp" } } }

VS Code (GitHub Copilot). In .vscode/mcp.json or with "MCP: Add Server":

{ "servers": { "keyio": { "type": "http", "url": "https://gokeyio.com/api/mcp" } } }

Any other MCP client. Add a remote server with Keyio’s address. If the client follows the MCP authorization spec (OAuth 2.1 with dynamic client registration), sign-in works the same way.

Menus change with each version of these apps; if you cannot find the option, look for "MCP" or "connector" in their settings. When you connect, Keyio opens for you to sign in and allow access.

Read only

Looks at properties, rentals, expenses and invoices, payments, documents, maintenance, tax reports and templates. Changes nothing and cannot see your guests’ details.

Read and write

Also creates, changes and deletes data, sees and edits guests, and files guest registrations with SES.

You can ask

  • “Which of my homes have no booking next month?”
  • “Add a €120 water bill for Calle Mayor 3, dated today.”
  • “Add the guests of the booking that starts on Friday.”
  • “Send that booking’s guest registration to SES.”
  • “File the invoices waiting in my invoice inbox.”
  • “Record that the tenant at Calle Mayor 3 paid October’s rent by transfer.”
  • “How much did my rentals earn this year, property by property?”
  • Filing with SES is real and cannot be undone. The assistant only does it when you ask, and only for properties where you turned on automatic SES sending in the app.
  • SES credentials cannot be set through the assistant, so your password never goes through a chat.
  • In claude.ai, Claude cannot pass a file you attach in the chat on to Keyio. To get an invoice in, forward it to your account’s invoice mailbox and ask it to file it; in Claude Desktop or Claude Code it can attach a file from your computer.
  • Disconnect it at any time in Settings → Developer → Connected apps; it loses access on its next request.

If the client supports headers, you can also use an API key from Settings → Developer instead of OAuth:

claude mcp add --transport http keyio https://gokeyio.com/api/mcp \
  --header "Authorization: Bearer kk_live_…"

Getting started

  1. In Keyio, open Settings → Developer and create a key. Choose read-only unless your program has to make changes. The key is shown once: store it like a password.
  2. Send it on every request in the Authorization header.
curl https://gokeyio.com/api/v1/properties \
  -H "Authorization: Bearer kk_live_…"
  • Base URL: https://gokeyio.com/api/v1
  • JSON requests and responses (Content-Type: application/json when there is a body).
  • ISO YYYY-MM-DD dates. Amounts in euros, as numbers.

Authentication

Every request carries Authorization: Bearer …. There are two ways to get one:

API key

For your own scripts and integrations. It does not expire; revoke it in Settings → Developer and it stops working on the next request.

OAuth 2.1

For an app that connects on your behalf, such as Claude or ChatGPT. The app sends you to Keyio, you sign in and choose what it may do; it receives a one-hour token that renews itself. Keyio follows the MCP authorization spec (2025-06-18).

Protected resource metadatahttps://gokeyio.com/.well-known/oauth-protected-resource/api/mcp
Authorization server metadatahttps://gokeyio.com/.well-known/oauth-authorization-server
Client registrationPOST https://gokeyio.com/api/oauth/register
Authorizationhttps://gokeyio.com/auth/oauth/authorize
TokenPOST https://gokeyio.com/api/oauth/token
RevocationPOST https://gokeyio.com/api/oauth/revoke
  • Public clients only (token_endpoint_auth_method: none), with PKCE S256 required.
  • Redirect URIs must be https, or http on the loopback interface (localhost, 127.0.0.1) with any port.
  • Refresh tokens rotate on every use and last 90 days. Presenting a used one revokes the whole connection.
  • Scopes: keyio:read and keyio:write (implies read). The user can grant less than requested.

Read (keyio:read)

Every GET, except guest data.

Read/write (keyio:write)

Everything: create, update, delete, guests and filing with SES.

A key or token never grants more than its owner’s own login, and stops working if the account is suspended or deleted.

Permissions

You are…ReadRentals, expenses, guestsChange or delete the property
Owner of the property
Editor (shared with you)
Viewer or calendar collaborator

Expenses (with their invoices, recurring expenses and the inbox) need a plan with expenses and templates one with contracts (every plan except Cumplimiento); payments, maintenance and reports, a plan with that feature. Otherwise the API answers 403. Templates are yours only and never shared.

Limits, paging and errors

LimitPer minutePer day
All requests, per key602,000
Writes and guest reads, per key60500
Per IP address300—

A write counts against both per-key limits. Over a limit the API answers 429 until the window passes. Daily limits are exact; per-minute ones are counted per server and are approximate.

Every list (except guests) returns one page: { "rentals": [...], "nextCursor": "…" }. Use limit (1–200, default 100) and cursor with the previous nextCursor; it is null on the last page. A cursor that no longer exists is a 400: start again.

In a PATCH, an object (sale, touristTax, energyCertificate…) is merged into the stored one field by field: what you leave out is kept. A list (owners, budgetLines, lines…) is replaced whole. The response is the record as stored.

Files (invoices, documents, photos) travel inside the JSON: { "fileName": "invoice.pdf", "mimeType": "application/pdf", "contentBase64": "…" }, up to 10 MB; the type is checked from the content. Reading one returns fileName, mimeType, size and a signed downloadUrl valid for 15 minutes; with ?content=true, also contentBase64 (up to 5 MB). When the client cannot send the file, POST /upload-links (expenseId, propertyId or rentalId with document.name, or inbox: true) returns a one-time link — 30 minutes, no sign-in — to pick it on your phone.

400Invalid body or query. Includes fieldErrors. Unknown fields and parameters are rejected. So is an empty PATCH.
401Missing, invalid, revoked or expired key or token, or the account is suspended.
403Read-only key on a write, a plan without the feature, a plan limit reached, or only its author can delete that record.
404Does not exist or is not yours; deliberately not distinguished.
409Conflicts with the record’s state (see each resource).
410/assets was retired: { "error": "deprecated", "message": "…" }.
422Well-formed but cannot be carried out (guest registration).
429Rate limit exceeded.
500Our error. A GET can be retried; for a write, check first whether it was applied.
502SES did not accept, or did not clearly answer, a guest registration.
{ "error": "Validation failed", "fieldErrors": { "date": ["Must be an ISO date (YYYY-MM-DD)"] } }

Checks run in this order: per-IP limit → key → per-key limits → read-only key → write limit → plan → body → access to the record → the record’s state. The first that fails decides.

Reference

Paths are relative to https://gokeyio.com/api/v1. Bold with *, required on create.

Properties

RouteScopeAnswers
GET/propertiesread200 { properties, nextCursor }
GET/properties/{id}read200 { property } · 404
POST/propertiesread/write201 { property } · 400 · 403
PATCH/properties/{id}read/write · owner200 { property } · 400 · 404
DELETE/properties/{id}read/write · owner200 · 404 · 409

Fields you can send

name *address *cadastralRef *cadastralValue *landValue *acquisitionDate *cadastralValueRevisedconstructionValueacquisitionCostsurfaceAreamainPurposesaletaxRegimenonResidentEUpaymentTrackingEnabledregistrationNumberarchivedcalendarEnabledcitycountrystateRegionamortizationStrategyenergyCertificatetouristTaxdefaultExtrascommunicationsbankAccountownersrepresentativesesCredentials
  • mainPurpose: long_term, short_term or sale (bought to be sold). sale is buy-to-sell tracking: stage, target price, budget lines, financing, deeds, municipal capital-gains tax and sale price and date.
  • taxRegime: es-individual, es-company or es-nonresident (with nonResidentEU when the owner resides in the EU/EEA). paymentTrackingEnabled turns on rent payment tracking for the property’s rentals; it is needed to record payments.
  • SES, Mossos and Ertzaintza credentials, calendar feed links and sharing settings are never returned. The IBAN and the ID numbers of owners and representative are only shown to the owner and editors.
  • Automatic SES sending (sesAutoSend) and sharing can only be changed in the app. Creating respects the plan’s property limit (403).
  • Deleting is refused with 409 while there are rentals or expenses; it also deletes its documents and checklist history. It cannot be undone.

Rentals

RouteScopeAnswers
GET/rentalsread200 { rentals, nextCursor }
GET/rentals/{id}read200 { rental } · 404
POST/rentalsread/write · owner or editor201 { rental } · 400 · 404 · 409
PATCH/rentals/{id}read/write · owner or editor200 { rental } · 400 · 404
DELETE/rentals/{id}read/write · owner or editor200 · 404

List filters

  • propertyId — Only that property’s (404 if it is not yours).
  • type — long or short.
  • from, to — Stays that overlap the range.

Fields you can send

propertyId *startDate *contractStartDate *yearlyIncome *nameendDatetyperenterNamerenterAddressrenterscheckInTimecheckOutTimeadvancedPaymentremainingBalancepaymentPlanextrasdiscountAmountdiscountReasondiscountNoteextraChargesyearcontractCommissionscommissionTypedepositadjustmentsvariationsdepositEntriespaymentTrackingEnabled
  • renters takes id, fullName, idNumber, address, phone and email, but only returns id and fullName. In a PATCH, a renter with a known id keeps what you leave out; an empty string clears a field; one missing from the list is removed. renterAddress is not returned (it is a home address).
  • Creating on a sold property gives 409. propertyId cannot be changed.
  • Deleting also removes payments, notes, documents and signing links, revokes the door code and, for a Basque booking already reported, leaves the reminder to cancel it with the Ertzaintza.

Expenses

Needs a plan with expenses.

RouteScopeAnswers
GET/expensesread200 { expenses, nextCursor }
GET/expenses/{id}read200 { expense } · 404
POST/expensesread/write · owner or editor201 { expense } · 400 · 404
PATCH/expenses/{id}read/write · owner or editor200 { expense } · 400 · 404
DELETE/expenses/{id}read/write · owner or editor200 · 404
GET/expenses/{id}/fileread200 { file } · 404
PUT/expenses/{id}/fileread/write · owner or editor200 { expense } · 400 · 404
DELETE/expenses/{id}/fileread/write · owner or editor200 · 404
GET/recurring-expensesread200 { recurringExpenses, nextCursor }
PATCH/recurring-expenses/{id}read/write · owner200 { recurringExpense } · 400 · 404
DELETE/recurring-expenses/{id}read/write · owner200 · 404

List filters

  • propertyId — Only that property’s.
  • year — Fiscal year, four digits.

Fields you can send

propertyId *type *amount *date *year *descriptionissuerNameissuerIdamortizationTypeamortizationDurationamortizationRaterepairCausedByTenantexclusiveToRentaloperationCategorybudgetLineIdinvoiceNumbertaxBasevatAmountuntaxedAmountwithholdingAmountlinesdueDaterecurrencefile
  • type is free text, but use one of the app’s categories so it counts in the tax report: Seguro, Comunidad, Impuestos, Suministros, Conservación, Reparaciones, Mobiliario, Electrodomésticos, Intereses de Hipoteca, Formalización Contrato, Defensa Jurídica, Servicios Personales, Otros. IBI is stored as Impuestos.
  • A fixed asset (furniture, appliance) is a Mobiliario or Electrodomésticos expense with amortizationType "investment". The old /assets routes answer 410.
  • Breakdown (companies): amount should be taxBase + vatAmount + untaxedAmount; the withholding is informative. The API stores what you send without checking the sums. payment (what bank reconciliation recorded as paid) is read-only.
  • recurrence (create only): { frequency: monthly | quarterly | yearly, nextDueDate, endDate }. It creates the periods already due up to today (at most 120) and a recurring expense that is copied on each due date; the response adds recurring: { recurringExpenseId, backfilled, nextDueDate }. The expense does not store the recurrence and a PATCH does not accept it (400): change or stop it through /recurring-expenses.
  • file (on create) or PUT /expenses/{id}/file attach the invoice: PDF, JPEG, PNG, WebP or GIF; replacing deletes the old one. Deleting the file keeps the expense.
  • /recurring-expenses: your own only (filter propertyId). PATCH takes type, description, issuerName, issuerId, frequency, nextDueDate, lastAmount, endDate (null clears it), active and operationCategory. DELETE stops the repetition; expenses already created stay.

Invoice inbox

Needs a plan with expenses. It belongs to the account owner: invoices uploaded without a property or forwarded by email wait here until they are filed as an expense.

RouteScopeAnswers
GET/inboxread200 { mailbox, items, nextCursor }
PUT/inbox/mailboxread/write · owner200 { mailbox } · 409
GET/inbox/{id}read200 { item, file } · 404
POST/inbox/{id}/fileread/write · owner201 | 200 { expense } · 400 · 404 · 409
DELETE/inbox/{id}read/write · owner200 · 404

Fields you can send

expenseIdexpenseallowedSenders
  • GET /inbox returns the invoices oldest first and the mailbox: { available, address, accountEmail, allowedSenders }. PUT /inbox/mailbox turns it on (always the same address) and takes allowedSenders; 409 when the mailbox is not available.
  • POST /inbox/{id}/file takes exactly one of: expenseId (attaches the invoice to that expense, 200) or expense (the same fields as POST /expenses, creates it, 201). The invoice leaves the inbox. 409 when it has no file.
  • The API never runs Keyio’s AI on the invoice: the caller (your program or your assistant) reads it and decides the property and the figures.

Documents

Of a property (/properties/{id}/documents) or of a rental (/rentals/{id}/documents), with the same routes.

RouteScopeAnswers
GET/properties/{id}/documentsread200 { documents, nextCursor }
GET/rentals/{id}/documentsread200 { documents, nextCursor }
GET…/documents/{docId}read200 { document, file } · 404
POST…/documentsread/write · owner or editor201 { document } · 400 · 404
PATCH…/documents/{docId}read/write · owner or editor200 { document } · 400 · 404
DELETE…/documents/{docId}read/write · owner or editor200 · 404 · 409

Fields you can send

name *descriptiondocumentTypevalidityDatepublishedToPortalfile *
  • documentType: contract, addendum, inventory, checkin_report, checkout_report, receipt, invoice, deposit, id_copy, insurance, deed, energy_certificate, habitability_certificate, tourist_license, house_rules, appliance_instructions, wifi_info or other. file: PDF, images, Word, Excel or OpenDocument. A rental’s are created published.
  • Returned with status (draft, published, archived, pending_signature, signed), hasFile and signing (how many signers and how many signed), never links or signer details. GET of one adds file: for a signed contract, the signed PDF.
  • PATCH: name, description, documentType, validityDate (null clears it) and publishedToPortal. Deleting is refused with 409 while it is pending signature, and also deletes its files.

Rent payments

Needs a plan with payments and payment tracking turned on for the property (paymentTrackingEnabled).

RouteScopeAnswers
GET/rentals/{id}/paymentsread200 { trackingEnabled, charges, otherPayments } · 404
POST/rentals/{id}/paymentsread/write · owner or editor201 { payment } · 400 · 404 · 409
PATCH/rentals/{id}/payments/{paymentId}/entries/{entryId}read/write · owner or editor200 { payment } · 400 · 404
DELETE/rentals/{id}/payments/{paymentId}/entries/{entryId}read/write · owner or editor200 · 404
DELETE/rentals/{id}/payments/{paymentId}read/write · its author only200 · 403 · 404

List filters

  • year — Only that year’s charges.

Fields you can send

yearmonthchargeTypeplanEntryIdamount *date *methodnotes
  • Charges: for a long-term let, one per month up to next month; for a short stay, the deposit and balance or the milestones of its paymentPlan. Each has chargeType (monthly_rent, advance, balance, installment), expectedAmount, receivedAmount, status (paid, partial, pending, due, late) and its entries.
  • To record a payment, name the charge with year + month, chargeType or planEntryId. It adds to what was already received: paid once the expected amount is reached, partial before. If the charge is ambiguous, the 400 lists them. method: transfer (default), cash, card, domiciliacion or other. 409 when payment tracking is off.
  • A single payment is corrected or removed at …/entries/{entryId}; removing the last one deletes the record. Only whoever recorded it can delete the whole charge (403).

Rental notes

The rental’s communications log. Notes cannot be edited.

RouteScopeAnswers
GET/rentals/{id}/notesread200 { notes, nextCursor }
POST/rentals/{id}/notesread/write · owner or editor201 { note } · 400 · 404
DELETE/rentals/{id}/notes/{noteId}read/write · its author only200 · 403 · 404

Fields you can send

content *typecontactDirectionoccurredAt
  • content up to 2,000 characters. type: note, call, email, whatsapp, letter, meeting or other; contactDirection: inbound or outbound. createdBy is your account’s name. Listed newest first; only its author can delete one.

Maintenance

Needs a plan with maintenance.

RouteScopeAnswers
GET/maintenanceread200 { maintenanceRequests, nextCursor }
GET/maintenance/{id}read200 { maintenanceRequest } · 404
POST/maintenanceread/write · owner or editor201 { maintenanceRequest } · 400 · 404
PATCH/maintenance/{id}read/write · owner or editor200 { maintenanceRequest } · 400 · 404
DELETE/maintenance/{id}read/write · its author only200 · 403 · 404
POST/maintenance/{id}/photosread/write · owner or editor201 { maintenanceRequest } · 400 · 404 · 409
GET/maintenance/{id}/photos/{n}read200 { file } · 404
DELETE/maintenance/{id}/photos/{n}read/write · owner or editor200 { maintenanceRequest } · 404

List filters

  • propertyId — Only that property’s.
  • status — open, acknowledged, in_progress, completed or cancelled.

Fields you can send

propertyId *rentalIdtitle *descriptioncategoryurgencystatusassignedToestimatedCostactualCostnoteslinkedExpenseId
  • category: plumbing, electrical, hvac, appliance, structural, cleaning or other (default); urgency: low, medium (default), high or emergency; status starts as open. notes up to 2,000 characters. linkedExpenseId (PATCH only) links an expense of the same property; null unlinks it. Completing it stamps resolvedAt.
  • Up to 5 photos per request (one image per POST; 409 beyond 5); n starts at 1. photoCount is returned, never photo links. Only whoever created it can delete it (otherwise cancel it); deleting it deletes its photos.

Tax reports

Needs a plan with reports. They are estimates and always carry the disclaimer to check them with your tax adviser.

RouteScopeAnswers
GET/properties/{id}/tax-reportread200 { report } · 400 · 404
GET/reports/summaryread200 { year, properties, totals, disclaimer } · 400

List filters

  • year — Required on both.
  • isRatePct — 15 or 25: corporate tax rate (report of a company-owned property).
  • A property’s report has regime (IRPF, IS or IRNR), owners with their ownershipPercentage, occupancy, income, expenses by tax-return box, the irpf detail (net return, long-term letting reduction, imputed income), is or irnr, and result { deductions, netResult, estimatedTax }. Figures are for 100% of the property.
  • The summary gives, per property with activity that year, income, deductible expenses, net result and estimated tax, plus the totals.

Contract templates

Needs a plan with contracts. They are yours only.

RouteScopeAnswers
GET/templatesread200 { templates, nextCursor }
GET/templates/{id}read200 { template } · 404
POST/templatesread/write201 { template } · 400
PATCH/templates/{id}read/write200 { template } · 400 · 404
DELETE/templates/{id}read/write200 · 404

Fields you can send

name *language *content *category
  • content is a TipTap document: { "type": "doc", "content": [ … ] }, the same format as the app’s editor. category: rental-contract, short-term-rental, rent-review, inventory, termination, addendum or other.

Guest registration

  • Every guest route, the GET included, needs a read/write key and counts against the write limit. A read key never sees guests.
  • They are returned masked: the last two characters of the document, the year of birth and whether there is an email and a phone. Never the full document, date of birth, address, email or phone.
  • Each guest carries sesReady and missing: what is still needed for a valid filing. You can create one with just a first and last name and complete it step by step.
  • Once filed, or while being filed, they cannot be changed (409).
RouteScopeAnswers
GET/rentals/{id}/guestsread/write200 { registration, guests } · 404
POST/rentals/{id}/guestsread/write · owner or editor201 { guest } · 400 · 404 · 409
PATCH/rentals/{id}/guests/{guestId}read/write · owner or editor200 { guest } · 400 · 404 · 409
DELETE/rentals/{id}/guests/{guestId}read/write · owner or editor200 · 404 · 409
POST/rentals/{id}/guests/submitread/write · owner or editor200 · 403 · 404 · 409 · 422 · 502
POST/rentals/{id}/guests/ses-statusread/write · owner or editor200 · 404 · 409 · 422 · 502
POST/rentals/{id}/guests/ses-cancelread/write · owner or editor200 · 400 · 404 · 409 · 422 · 502
GET/rentals/{id}/libro-viajerosread/write · owner or editor200 · 403 · 404
GET/properties/{id}/libro-viajerosread/write · owner or editor200 · 400 · 403 · 404
GET/properties/{id}/ertzaintzaread200 · 404
POST/rentals/{id}/ertzaintza/fileread/write · owner or editor200 · 404 · 422

Guest fields

firstName *lastName *secondSurnamedocTypedocIdsupportNumberdocIssueDatedocExpirationDatedobnationalitysexstreethouseNumberflatpostalCodecitymunicipalityCodeprovincecountryOfResidencephoneNumberemailisMinorNoDocparentIdrelationship

POST /rentals/{id}/guests/submit files the registration with SES.Hospedajes. It is a real submission to the authorities and cannot be undone through the API.

It only works when:

  • The owner has turned on automatic SES sending for that property, in the app.
  • The property reports to SES. The Basque Country reports to the Ertzaintza: the API gives the XML file for its portal; Catalonia (Mossos) is filed from the app.
  • It has SES credentials, with establishmentCode and codigoArrendador.
  • Every guest is complete (sesReady: true).
200Filed: { submitted: true, loteId, verification }.
403Automatic SES sending is off. Turn it on in the app.
409Already filed, or a submission is in progress or a recent one ended without a clear answer. Do not retry: check in Keyio.
422Not fileable: region, credentials, no guests or incomplete guests (the response says what each is missing). Fix and submit again.
502"Nothing was filed": SES rejected it, fix and retry. "May or may not have been accepted": do not retry; further attempts are refused for 15 minutes.

Only one submission per rental runs at a time, so two calls cannot file the same registration twice. Never retry automatically after an error or a timeout.

Activity log

Every call made with a valid key is recorded with method, path, status, IP and user agent for 90 days, except those refused by a limit or by validation. You see it in Settings → Developer → Recent activity.

FAQ

Does Keyio have an MCP server?

Yes. Keyio offers a remote MCP server at https://gokeyio.com/api/mcp, with OAuth sign-in, on every plan. It gives an AI assistant access to your properties, rentals, expenses and their invoices, invoice inbox, rent payments, maintenance, notes, documents, tax reports, contract templates and guest registration, with the same permissions you have in the app.

Can I use Keyio with ChatGPT or Claude?

Yes. In Claude you add it as a custom connector and click Connect; in ChatGPT, as a connector in developer mode. It also works with Claude Code, Cursor, VS Code and other MCP-compatible clients.

What can an AI assistant do with Keyio?

With read access, answer questions about your properties, bookings, income, expenses, payments, maintenance and the year’s tax summary. With write access, also record expenses with their invoice, file the invoices in the inbox, record rent payments, open maintenance requests, upload documents, create or change rentals, add guests step by step and file the guest registration with SES.HOSPEDAJES when you ask.

Is it safe to connect an AI assistant to my data?

You choose in Keyio whether it can only read or also make changes, and you can disconnect it at any time. It never sees more than you do, guest data is masked, SES credentials can never be read or set from the assistant, and every call is logged.

How much does the API or MCP server cost?

Nothing extra: they are included in every Keyio plan, the Cumplimiento plan too.

Questions, or something that does not work as described here? Write to us. Contact →