Developers · Connect v1

Module definition

Describe your CoSuite modules in the manifest (contract 1.7). Features, API with OpenAPI 3.1 and scopes, webhooks, provides, data categories and markets, plus the rules the conformance test enforces.

Since contract version 1.7, each module in your manifest can describe itself in detail. The CoSuite catalog, the sign-up flow, your app's page in CoSuite, the cosuite.io product pages and (in phase 2) the customer API reference are all generated from these fields. Every field is optional; a 1.6 manifest stays valid as it is.

Example

{
  "key": "dent.treatment",
  "name": { "tr": "Hasta ve tedavi planı", "en": "Patients and treatment plans", "az": "Xəstə və müalicə planı" },
  "description": { "tr": "Hasta kartı ve tedavi planı.", "en": "Patient records and treatment plans.", "az": "Xəstə kartı və müalicə planı." },
  "limits": [{ "key": "smsPerMonth", "unit": "count_per_month" }],
  "features": [
    { "key": "plan_pdf", "name": { "tr": "Tedavi planı PDF'i", "en": "Treatment plan PDF", "az": "Müalicə planı PDF" } },
    { "key": "sms", "name": { "tr": "SMS hatırlatma", "en": "SMS reminders", "az": "SMS xatırlatma" }, "limit": "smsPerMonth" }
  ],
  "api": { "version": "2026-11", "openapi": "/openapi.json", "scopes": [{ "key": "patients:read" }, { "key": "patients:write" }] },
  "webhooks": [{ "type": "treatment.completed", "scope": "patients:read", "schema": { "type": "object" } }],
  "provides": [],
  "dataCategories": ["identity", "contact", "health"],
  "markets": [
    { "country": "TR", "locales": ["tr"] },
    { "country": "AZ", "locales": ["az"], "price": { "currency": "AZN", "amount": 25 } }
  ]
}

Fields

Field Meaning
key, name, limits, usage Unchanged from earlier versions (see the contract). Module key <appKey>.<module>; name per language, up to 200 characters.
description Per-language description, up to 1000 characters.
features[] The module's capabilities: key (lowercase, ^[a-z][a-z0-9_]*$), per-language name, optional per-language description and an optional limit it depends on (one of the same module's limits[].key).
api The endpoints the module exposes to customers. openapi: an OpenAPI 3.1 document, either a URL (https, or a path relative to baseUrl; JSON only, at most 2 MB) or an embedded object. scopes[]: the module's scopes in resource:action form (patients:read), each with an optional per-language name. version: your API version.
webhooks[] Events the module emits: type (dotted lowercase, for example treatment.completed), optional per-language name and description, an optional subscription scope (one of api.scopes) and a JSON Schema for data.
provides[] Shared business functions the module takes over in CoSuite: crm, quotes, einvoice, expenses, inventory, projects, inbox, booking, reviews, payments, reports, website, seo, social, shipping, hr, pos. Two modules never provide the same function for the same business at the same time.
dataCategories[] Personal data the module processes: identity, contact, financial, health, location, biometric, children, communications, media, usage, employment, legal. Used for privacy notices (GDPR, KVKK) and review.
markets[] Countries where the module is offered (country, ISO 3166-1 alpha-2) and their languages (locales, taken from the manifest's locales); an optional country price { currency, amount }. If empty, the market is decided in CoSuite.

Limits at a glance: up to 64 features, 64 scopes, 64 webhooks, 16 provides, 32 data categories and 100 markets per module.

Rules the conformance test enforces

The conformance test checks only the fields you fill in. The partner portal runs the same checks when you submit.

  • Texts in every market language. For every locale used in markets, the module's name, its description and every feature's name must be filled in.
  • Market locales come from the manifest. Each locale in markets[].locales must also be in the manifest's locales.
  • No duplicate keys in features, api.scopes, webhooks (by type) and markets (by country); no duplicates in provides.
  • Feature limits exist. A feature's limit must be one of the module's limits[].key.
  • Webhook scopes exist. A webhook's scope requires an api definition and must be one of api.scopes.
  • Known values only. provides and dataCategories accept only the values listed above. CoSuite itself ignores unknown values (forward compatibility), but the test rejects them to catch typos.
  • OpenAPI is checked for every module with an api: the document is downloaded (or read inline) and validated as described below.

OpenAPI requirements

The test checks the parts CoSuite relies on; it is not a full schema validation.

  • openapi is 3.1.x; info.title and info.version are present; paths is not empty and every path starts with /.
  • Every operation requires at least one scope through the cosuite security scheme: security: [{ "cosuite": ["<scope>"] }]. An operation without its own security inherits the root-level security.
  • Every scope used in the document must be declared in the module's api.scopes.
  • operationId values are unique.
  • When openapi is a URL it must be https if your baseUrl is https, must return 200 with JSON (YAML is not supported) within 10 seconds, without redirects, and must be at most 2 MB.

A minimal valid document:

{
  "openapi": "3.1.0",
  "info": { "title": "DentCloud treatment API", "version": "2026-11" },
  "security": [{ "cosuite": ["patients:read"] }],
  "components": {
    "securitySchemes": {
      "cosuite": { "type": "http", "scheme": "bearer", "bearerFormat": "CoSuite API key", "description": "CoSuite customer API key; the gateway checks the scopes in security" }
    }
  },
  "paths": {
    "/patients": {
      "get": { "operationId": "listPatients", "responses": { "200": { "description": "Patients" } } },
      "post": {
        "operationId": "createPatient",
        "security": [{ "cosuite": ["patients:write"] }],
        "responses": { "201": { "description": "Created" } }
      }
    }
  }
}

The cosuite scheme above is the final definition: customers send their CoSuite API key as a bearer token to the gateway, which checks the scopes listed in security. Optionally set servers[0].url to the base path of your API on the same origin as your app (for example https://app.dentcloud.example/api); the gateway forwards requests there.

How customers reach your API

Customers call your module's endpoints through CoSuite's gateway at api.cosuite.io with their own CoSuite key. The request reaches your app with a Connect signature and an X-CoSuite-Tenant header that tells you which business is calling. See Gateway & customer API for the headers, your obligations and the error codes.

Markets and languages

  • A customer only sees modules that are offered in their own country. If you list markets, your module is shown only in those countries.
  • Text is required in each market's languages (see rules). Other languages are optional.
  • price sets a local price for that country. Without it, CoSuite converts the module's USD price at the current exchange rate.
  • If markets is empty or missing, CoSuite decides where the module is offered.

Keys are permanent

Module, feature, limit, scope and webhook keys are part of the contract once your module is live. Do not rename them; add a new key and keep the old one for at least 6 months (see versioning).