# authorship: generated by API Evangelist tooling. Stamped 2026-08-18 # on the file's own generator header (roadmap#64). An unmarked file is # NOT assumed to be ours -- absence of evidence was never stamped. x-method: generated overlay: 1.0.0 info: title: API Evangelist enhancements for the BioFlyte Customer Portal API (AdminWeb) version: 1.0.0 extends: openapi/bioflyte-portal-openapi-original.json x-generated: '2026-08-07' x-method: generated x-source: >- API Evangelist enrichment pipeline. The extended document is BioFlyte's own OpenAPI 3.0.1, saved VERBATIM from https://portal.bioflyte.com/swagger/v1/swagger.json on 2026-08-07 and never modified. Everything we observed or inferred lives here instead, so the harvested spec stays a faithful copy of what the provider serves. actions: - target: $.info update: description: >- The HTTP API behind portal.bioflyte.com, BioFlyte's authenticated customer console for managing deployed BioTOF aerosol sensors — alert settings and recipients, device, organization, location, user, role and telemetry-type lookups, a device location map, file upload/download, permission resolution and organization switching. Titled "AdminWeb" and generated by Swashbuckle from ASP.NET Core controllers. contact: name: BioFlyte url: https://www.bioflyte.com/ x-apievangelist-profile: https://apis.io/providers/bioflyte/ x-apievangelist-artifacts: data_model: data-model/bioflyte-data-model.yml conventions: conventions/bioflyte-conventions.yml errors: errors/bioflyte-problem-types.yml lifecycle: lifecycle/bioflyte-lifecycle.yml conformance: conformance/bioflyte-conformance.yml event_surface: asyncapi/bioflyte-event-surface.yml agentic_access: agentic-access/bioflyte-agentic-access.yml x-provider-published: true x-harvested-from: https://portal.bioflyte.com/swagger/v1/swagger.json x-harvested-on: '2026-08-07' - target: $.info update: x-access-note: >- The DESCRIPTION is public; the API is not. Every operation probed anonymously on 2026-08-07 returned HTTP 302 to https://portal.bioflyte.com/identity/account/login?ReturnUrl=... — no error body, no code. A client that follows the redirect receives an HTML login page with HTTP 200, which is a success status for a denied call. x-documentation-note: >- BioFlyte does not link, announce, version or support this document. The only reference is the Swagger UI at /swagger/index.html, which is generated scaffolding rather than written documentation. There is no developer portal, no getting-started guide and no contact for this API anywhere on bioflyte.com. - target: $.info update: x-spec-quality-gaps: - No `servers` block — the base URL is not declared anywhere in the document. - No `components.securitySchemes` and no `security` on any operation, so the document does not state how to authenticate an API that requires authentication for every call. - No `operationId` on any of the 40 operations. - No `summary` or `description` on any operation. - Every operation declares exactly one response, 200 "OK" — no 4xx, no 5xx, no error schema. - 38 of 40 operations declare no response schema, so a client cannot know the shape of what it receives. - Core domain objects (Device, Organization, Location, Alert, Sample, User, Role) have no schema in components. - No examples anywhere in the document. x-spec-quality-note: >- These are Swashbuckle defaults, not deliberate choices — the C# types already exist behind the controllers. Annotating the controllers would close most of this without any new API work. - target: $.info update: x-observed-host: portal.bioflyte.com x-observed-server: Kestrel (ASP.NET Core) x-observed-tls: TLSv1.3 x-observed-cert-issuer: Let's Encrypt x-observed-hsts: max-age=2592000 x-observed-hsts-note: >- 30 days, without includeSubDomains and without preload — weaker than the one-year includeSubDomains+preload policy on www.bioflyte.com. - target: $.paths['/LoadLocationMapData'].post update: x-domain-note: >- Takes dbFileId, locationId and deviceId, so a location's map is an uploaded file (see the Files tag) that devices are placed onto — this is the floor-plan view of a deployment. - target: $.paths['/SwitchOrganization'].post update: x-domain-note: >- Confirms multi-tenancy: a portal user can hold membership in more than one organization and switch the active tenant within a session. - target: $.paths['/GetPermissions'].post update: x-domain-note: >- PermissionsReq carries both grantedPermissions[] and deniedPermissions[] as int32 arrays, so the authorization model supports explicit negative permissions layered on roles, not only additive grants. - target: $.paths['/TestOnSampleReceived'].post update: x-domain-note: >- An event test hook. Together with /TestOnAlertsUpdated and /Test/TestOnSampleStatusUpdated and the NewSampleReceived / AlertsUpdated schemas, it evidences a sample-and-alert event pipeline that BioFlyte publishes no AsyncAPI or webhook reference for. Recorded in asyncapi/bioflyte-event-surface.yml. - target: $.paths['/DownloadFile'].get update: x-domain-note: >- Takes a uuid `id` query parameter and is the only operation besides /GetClientCountryCodeByIp and /Test/TestOnSampleStatusUpdated that is a GET; the rest of the surface is POST-shaped RPC ("Load*" calls), including read-only lookups.