API

524 endpoints.
14 modules.
One coherent surface.

ASP.NET Core 8 Minimal API — every endpoint authenticated via Auth0, scoped to the caller's tenant, audit-logged on mutation, and documented in OpenAPI 3. The API is the workhorse layer: the React UI calls it, every service composes through it, and the same 14 modules you license on the frontend show up here as the API's organizing taxonomy.

526
endpoints
Every one OpenAPI-documented
14
modules
M01–M14 vertical slices
5
surface tiers
Admin · User · Public · Auth · AI
100%
multi-tenant scoped
No endpoint leaks across tenants

Where the depth lives

Endpoint count per module, sorted by surface area. The largest modules (Assessments, AI, Security, Tasks) carry the workflow complexity; smaller ones (Fonts, Legal) are tighter substrate pieces.

  1. M13Assessments and Surveys77
  2. M09AI Models, Prompts, Agents, Avatars65
  3. M01Security52
  4. M08Tasks48
  5. M05Translation and Languages44
  6. M12Categories and Topics41
  7. M02Accounts35
  8. M06Notify Templates30
  9. M04Infrastructure and Logging28
  10. M14Vendor Marketplace28
  11. M07Messaging25
  12. M03Support23
  13. M10Fonts16
  14. M11Legal Policy Management14

Total — 526 endpoints across the 14 modules. Browse every one on the API coverage map.

Anatomy of one endpoint

What happens when a React UI calls POST /assessment/{id}/save — every layer the request touches before the response comes back.

POST/assessment/{id}/save
  1. L1
    React UI fires the requestonClick → useMutation → fetch with Bearer JWT
  2. L2
    Auth0 middleware validates the tokenJWT signature + audience + scope + expiry
  3. L2
    Endpoint handler in ApiAssessment.csMinimal API route — model bound, request validated
  4. L3
    AssessmentService.SaveAssessment()Multi-tenant guard · permission check · audit-log write
  5. L4
    AssessmentRepository.Save()Dapper + ADO.NET → sp_Assessment_Save
  6. L5
    SQL writes three tables in one transactionAssessment · AssessmentResponse · AuditLog
  7. L3
    TranslationService localizes response messagesCaller's language → keyed string lookup
  8. L1
    Response returned to React{ id, version, lastModified, errors? }

One endpoint, three layers

The same SaveAssessment route as it appears at L2 (endpoint definition), L3 (service interface), and L4 (repository call). Idiomatic across all 524 endpoints — learn one, read the rest at a glance.

L2

Endpoint — ApiAssessment.cs

group.MapPost("/assessment/{id:guid}/save", async (
    Guid id,
    [FromBody] SaveAssessmentRequest req,
    IAssessmentService svc,
    UserContext ctx) =>
{
    var result = await svc.SaveAsync(id, req, ctx);
    return result.IsSuccess
        ? Results.Ok(result.Value)
        : Results.UnprocessableEntity(result.Errors);
})
.RequireAuthorization("Assessment.Write")
.WithName("SaveAssessment")
.Produces<AssessmentDto>(200);
L3

Service — AssessmentService.cs

public async Task<Result<AssessmentDto>> SaveAsync(
    Guid id,
    SaveAssessmentRequest req,
    UserContext ctx)
{
    await _tenantGuard.Check(id, ctx.TenantId);
    await _audit.Log("Assessment.Save", id, ctx);

    var entity = await _repo.SaveAsync(
        id, req.MapToEntity(ctx));

    return Result.Ok(entity.MapToDto());
}
L4

Repository — AssessmentRepository.cs

public async Task<Assessment> SaveAsync(
    Guid id, Assessment entity)
{
    using var conn = _db.Open();
    return await conn.QuerySingleAsync<Assessment>(
        "sp_Assessment_Save",
        new {
            Id = id,
            entity.TenantId,
            entity.Title,
            entity.Questions,
            entity.Version
        },
        commandType: CommandType.StoredProcedure);
}

Five surface tiers

Every endpoint belongs to one tier. The tier determines who can call it, what auth shape applies, and what scope of data the call touches.

184

Admin

Tenant-admin and platform-admin operations — user management, role + permission assignment, translation registry, content moderation, system configuration. Locked behind elevated permissions.

162

User

Authenticated end-user surfaces — profile, preferences, notifications, messaging, tasks, assessments. Every endpoint scoped to the calling user's tenant + accessible records.

28

Public

Unauthenticated surfaces — language list, country list, public help content, news feed previews, legal policy fetch. The thin slice anyone can call without a token.

38

Auth

Sign-in, sign-out, signup, password reset, MFA enrollment, OAuth handoff, magic-link delivery. The handshake surface between Auth0 and the application.

112

AI / Workflows

AI provider calls, prompt-runner invocations, agent orchestration, scheduled workflow triggers, async job status. Wraps OpenAI / Anthropic / HeyGen / vendor SDKs with auth + audit + retry.

What you don't have to build

Every B2B SaaS API has to solve these. CleenUI ships them all already wired — every endpoint inherits them, no copy-paste boilerplate per route.

Auth & access

  • OAuth2 / JWT validation via Auth0
  • Role-based authorization (RBAC)
  • Permission-based authorization (granular ABAC)
  • Multi-tenant data isolation
  • Row-level access control
  • API-key auth for service-to-service calls

Data integrity

  • Audit history on every mutation
  • Soft-delete + restore
  • Optimistic concurrency tokens
  • Idempotency keys for unsafe operations
  • Translation registry for response messages
  • FluentValidation pipeline

Query surface

  • Pagination (cursor + offset variants)
  • Multi-predicate filtering
  • Multi-column sorting
  • Field projection / shape selection
  • Search across denormalized text indexes
  • Date-range + numeric-range queries

Operations

  • OpenAPI 3 spec auto-generation
  • Swagger UI hosted at /swagger
  • Per-route + per-tenant rate limiting
  • Response compression (Brotli + gzip)
  • CORS with allow-list config
  • Structured logging (Serilog → Application Insights)
  • OpenTelemetry tracing + metrics
  • Health-check endpoints

Patterns you'll see in every handler

The API is consistent — same shape across all 524 endpoints. Learn it once, read the rest at a glance.

Multi-tenant by default

Every authenticated endpoint resolves the caller's tenant context up front. Repositories scope queries automatically — never up to the endpoint handler to remember.

Soft-delete + restore

Mutations don't hard-delete. Every domain entity carries `IsDeleted` + `DeletedAt` + `DeletedBy`. A restore endpoint reverses any soft-delete; admins can see the history.

Audit log everywhere

Every state change emits an audit row — actor, timestamp, before/after diff. Surfaced via the /admin/audit endpoints, retained per tenant policy.

Optimistic concurrency

Updates require the version token returned by the prior read. Stale writes 409 cleanly; the client decides whether to retry or merge.

Idempotency on POSTs

Unsafe operations accept an `Idempotency-Key` header. The same key replays return the cached prior response — safe to retry under network failure.

Translated response strings

Error envelopes carry a key + localized text resolved against the translation registry. UI never has to know about server-side i18n.

Find any endpoint

Type to filter a representative sample of the surface. Try assessment, role, chat, or any HTTP method like post. The full searchable map of all 524 is on the coverage page.

  • POST/admin/permission/deleteM01 Security
  • POST/admin/permission/saveM01 Security
  • POST/admin/permissiongroups/filterM01 Security
  • POST/admin/permissions/filterM01 Security
  • POST/admin/role/deleteM01 Security
  • POST/admin/role/detailM01 Security
  • POST/admin/role/permissions/addM01 Security
  • POST/admin/role/permissions/removeM01 Security
  • POST/admin/role/saveM01 Security
  • POST/admin/role/users/addM01 Security
  • POST/admin/roles/filterM01 Security
  • POST/admin/users/rolesM01 Security
  • POST/admin/users/roles/addM01 Security
  • POST/admin/users/roles/removeM01 Security
  • POST/auth/change-passwordM01 Security
  • POST/auth/check-email-and-phone-numberM01 Security
  • POST/auth/create-social-media-login-urlM01 Security
  • POST/auth/create-social-media-signup-urlM01 Security
  • POST/auth/impersonateM01 Security
  • POST/auth/loginM01 Security
  • POST/auth/refresh-access-tokenM01 Security
  • POST/auth/send-forgot-password-emailM01 Security
  • POST/auth/send-forgot-password-textM01 Security
  • POST/auth/signupM01 Security
  • POST/auth/signup-from-auth0M01 Security
  • POST/auth/social-media-loginM01 Security
  • POST/auth/verify-forgot-password-textM01 Security
  • GET/health/auth-securedM01 Security
  • POST/public/session-tokenM01 Security
  • POST/account/detailsM02 Accounts
  • POST/account/filterM02 Accounts
  • POST/account/plan/saveM02 Accounts
  • POST/account/saveM02 Accounts
  • POST/account/subscription/synchronizeM02 Accounts
  • POST/account/user/addM02 Accounts
  • POST/account/user/filterM02 Accounts
  • POST/account/user/inviteM02 Accounts
  • POST/account/user/removeM02 Accounts
  • POST/admin/account/change-UserM02 Accounts
  • POST/admin/account/change-ownerM02 Accounts
  • POST/admin/account/detailM02 Accounts
  • POST/admin/account/updateM02 Accounts
  • POST/admin/accounts/filterM02 Accounts
  • POST/user/account/set-latestM02 Accounts
  • POST/user/activity/filterM02 Accounts
  • POST/user/alerts/addM02 Accounts
  • POST/user/alerts/allM02 Accounts
  • POST/user/alerts/removeM02 Accounts
  • POST/user/assign-handleM02 Accounts
  • POST/user/bill/downloadM02 Accounts
  • POST/user/blockM02 Accounts
  • POST/user/blockedM02 Accounts
  • POST/user/calendar/availabilityM02 Accounts
  • POST/user/calendar/event-type/allM02 Accounts
  • POST/user/calendar/scheduleM02 Accounts
  • POST/user/case-study/cloneM02 Accounts
  • POST/user/case-study/deleteM02 Accounts
  • POST/user/case-study/detailM02 Accounts
  • POST/user/case-study/filterM02 Accounts
  • POST/user/case-study/media/addM02 Accounts

+ 442 more matches. See all on the coverage map →

Run a request through the API right now

A 30-minute architecture review walks any endpoint of yours against the CleenUI API surface. Bring a route you'd otherwise spend a week scaffolding.

Book a 30-minute reviewOpen in Postman