# Admin Documentation: https://docs.guidelab.co/api-reference/admin ## Endpoints [#endpoints] | Method | Endpoint | | -------- | --------------------------------------------------------------------------------------------------------------------------- | | `POST` | [Adopt an untracked Stripe subscription](/api-reference/admin/adminAdoptUntrackedProviderSubscription) | | `POST` | [Anonymize (GDPR-erase) a user](/api-reference/admin/adminAnonymizeUser) | | `GET` | [Audit Stripe subscriptions GuideLab does not track](/api-reference/admin/adminAuditOrganizationProviderSubscriptions) | | `POST` | [Authorize whole-conversation deletion as platform legal](/api-reference/admin/adminOverrideConversationDeletion) | | `DELETE` | [Clear admin viewing organization](/api-reference/admin/adminClearViewingOrg) | | `POST` | [Create organization billing portal session](/api-reference/admin/adminCreateOrganizationBillingPortal) | | `POST` | [Create organization subscription checkout session](/api-reference/admin/adminCreateOrganizationSubscriptionCheckout) | | `GET` | [Get organization by ID](/api-reference/admin/adminGetOrganization) | | `GET` | [Get user by ID](/api-reference/admin/adminGetUser) | | `POST` | [Grant a complimentary (free) plan](/api-reference/admin/adminGrantComplimentaryPlan) | | `GET` | [List all organizations](/api-reference/admin/adminListOrganizations) | | `GET` | [List all users](/api-reference/admin/adminListUsers) | | `GET` | [List duplicate subscription compensations](/api-reference/admin/adminListSubscriptionQuarantines) | | `GET` | [List platform billing commands requiring or retaining review](/api-reference/admin/adminListPlatformBillingCommandReviews) | | `GET` | [List platform-custody retention holds](/api-reference/admin/adminListPlatformCustodyRetentionHolds) | | `POST` | [Preview a notification template](/api-reference/admin/adminPreviewNotification) | | `POST` | [Release a platform-custody retention hold](/api-reference/admin/adminReleasePlatformCustodyRetentionHold) | | `DELETE` | [Remove a member from an organization](/api-reference/admin/adminRemoveOrganizationMember) | | `POST` | [Requeue a failed organization closure](/api-reference/admin/adminRequeueOrganizationClosure) | | `POST` | [Requeue a failed patient erasure](/api-reference/admin/adminRequeuePatientErasure) | | `POST` | [Reset a user's two-factor authentication](/api-reference/admin/adminResetUserTwoFactor) | | `POST` | [Resolve one ambiguous platform billing command](/api-reference/admin/adminResolvePlatformBillingCommandReview) | | `POST` | [Retry duplicate subscription compensation](/api-reference/admin/adminRetrySubscriptionQuarantine) | | `DELETE` | [Revoke a complimentary (free) plan](/api-reference/admin/adminRevokeComplimentaryPlan) | | `POST` | [Send a test notification](/api-reference/admin/adminTestNotification) | | `POST` | [Send password reset email for a user](/api-reference/admin/adminSendPasswordReset) | | `POST` | [Set admin viewing organization](/api-reference/admin/adminSetViewingOrg) | | `PUT` | [Update an organization](/api-reference/admin/adminUpdateOrganization) | --- # Ai Documentation: https://docs.guidelab.co/api-reference/ai ## Endpoints [#endpoints] | Method | Endpoint | | ------ | -------------------------------------------------------------------------------- | | `POST` | [Generate an AI message for a conversation](/api-reference/ai/generateAiMessage) | --- # Archive Documentation: https://docs.guidelab.co/api-reference/archive ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ---------------------------------------------------------------------------- | | `POST` | [Archive a patient](/api-reference/archive/archivePatient) | | `POST` | [Archive an order](/api-reference/archive/archiveOrder) | | `GET` | [List archived orders](/api-reference/archive/listArchivedOrders) | | `GET` | [List archived patients](/api-reference/archive/listArchivedPatients) | | `POST` | [Restore an archived order](/api-reference/archive/restoreArchivedOrder) | | `POST` | [Restore an archived patient](/api-reference/archive/restoreArchivedPatient) | --- # Automations Documentation: https://docs.guidelab.co/api-reference/automations ## Endpoints [#endpoints] | Method | Endpoint | | -------- | --------------------------------------------------------------------------------- | | `POST` | [Create Automation](/api-reference/automations/createAutomation) | | `DELETE` | [Delete Automation](/api-reference/automations/deleteAutomation) | | `GET` | [Get Automation](/api-reference/automations/getAutomation) | | `GET` | [List Automation Executions](/api-reference/automations/listAutomationExecutions) | | `GET` | [List Automations](/api-reference/automations/listAutomations) | | `POST` | [Publish Automation](/api-reference/automations/publishAutomation) | | `POST` | [Restore Automation](/api-reference/automations/restoreAutomation) | | `POST` | [Run Automation](/api-reference/automations/runAutomation) | | `PATCH` | [Toggle Automation](/api-reference/automations/toggleAutomation) | | `PUT` | [Update Automation](/api-reference/automations/updateAutomation) | --- # Bundles Documentation: https://docs.guidelab.co/api-reference/bundles ## Endpoints [#endpoints] | Method | Endpoint | | -------- | --------------------------------------------------------------- | | `POST` | [Create a bundle](/api-reference/bundles/createBundle) | | `DELETE` | [Delete a bundle](/api-reference/bundles/deleteBundle) | | `GET` | [Get a bundle](/api-reference/bundles/getBundle) | | `GET` | [List bundles](/api-reference/bundles/listBundles) | | `PATCH` | [Partially update a bundle](/api-reference/bundles/patchBundle) | | `PUT` | [Update a bundle](/api-reference/bundles/updateBundle) | --- # Calendar Documentation: https://docs.guidelab.co/api-reference/calendar ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ----------------------------------------------------------------------------- | | `POST` | [Create a time-off entry](/api-reference/calendar/createCalendarTimeOff) | | `DELETE` | [Deactivate a time-off entry](/api-reference/calendar/deleteCalendarTimeOff) | | `GET` | [Get a time-off entry by ID](/api-reference/calendar/getCalendarTimeOff) | | `GET` | [Get organization working days](/api-reference/calendar/getWorkingDays) | | `GET` | [List time-off entries](/api-reference/calendar/listCalendarTimeOff) | | `POST` | [Seed UK bank holidays](/api-reference/calendar/seedCalendarHolidays) | | `PUT` | [Update a time-off entry](/api-reference/calendar/updateCalendarTimeOff) | | `PUT` | [Update organization working days](/api-reference/calendar/updateWorkingDays) | --- # Categories Documentation: https://docs.guidelab.co/api-reference/categories ## Endpoints [#endpoints] | Method | Endpoint | | -------- | --------------------------------------------------------------------------------- | | `POST` | [Create a category](/api-reference/categories/createCategory) | | `DELETE` | [Delete a category](/api-reference/categories/deleteCategory) | | `DELETE` | [Delete category guide media](/api-reference/categories/deleteCategoryGuideMedia) | | `DELETE` | [Delete category image](/api-reference/categories/deleteCategoryImage) | | `GET` | [Get a category](/api-reference/categories/getCategory) | | `GET` | [Get category guide media](/api-reference/categories/getCategoryGuideMedia) | | `GET` | [Get category image](/api-reference/categories/getCategoryImage) | | `GET` | [List categories](/api-reference/categories/listCategories) | | `POST` | [Reorder categories](/api-reference/categories/reorderCategories) | | `PATCH` | [Toggle category active status](/api-reference/categories/toggleCategory) | | `PUT` | [Update a category](/api-reference/categories/updateCategory) | | `POST` | [Upload category guide media](/api-reference/categories/uploadCategoryGuideMedia) | | `POST` | [Upload category image](/api-reference/categories/uploadCategoryImage) | --- # Checkout Documentation: https://docs.guidelab.co/api-reference/checkout ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ----------------------------------------------------------------------------------- | | `POST` | [Cancel Checkout Order Payment](/api-reference/checkout/cancelCheckoutOrderPayment) | | `POST` | [Confirm Checkout Payment](/api-reference/checkout/confirmCheckoutPayment) | | `POST` | [Create Payment Intent](/api-reference/checkout/createPaymentIntent) | | `POST` | [Get Checkout Payment Status](/api-reference/checkout/getCheckoutPaymentStatus) | --- # Clients Documentation: https://docs.guidelab.co/api-reference/clients ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ----------------------------------------------------------------------------- | | `GET` | [List clinic clients (doctors) for a lab](/api-reference/clients/listClients) | --- # Clinic Documentation: https://docs.guidelab.co/api-reference/clinic ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ------------------------------------------------------------------------------ | | `GET` | [List partner labs for the clinic](/api-reference/clinic/getClinicPartnerLabs) | --- # Clinic Finances Documentation: https://docs.guidelab.co/api-reference/clinic-finances ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ------------------------------------------------------------------------------------------------- | | `GET` | [Get Clinic Credit Note](/api-reference/clinic-finances/getClinicCreditNote) | | `GET` | [Get Clinic Finances Summary](/api-reference/clinic-finances/getClinicFinancesSummary) | | `GET` | [Get Clinic Invoice](/api-reference/clinic-finances/getClinicInvoice) | | `GET` | [Get Clinic Invoices By Order](/api-reference/clinic-finances/getClinicInvoicesByOrder) | | `GET` | [Get Clinic Payment Stripe Receipt](/api-reference/clinic-finances/getClinicPaymentStripeReceipt) | | `GET` | [Get Clinic Statement](/api-reference/clinic-finances/getClinicStatement) | | `GET` | [Get Clinic Stripe Status](/api-reference/clinic-finances/getClinicStripeStatus) | | `GET` | [List Clinic Credit Notes](/api-reference/clinic-finances/listClinicCreditNotes) | | `GET` | [List Clinic Invoices](/api-reference/clinic-finances/listClinicInvoices) | | `GET` | [List Clinic Statements](/api-reference/clinic-finances/listClinicStatements) | --- # Clinic Locations Documentation: https://docs.guidelab.co/api-reference/clinic-locations ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ------------------------------------------------------------------------------------ | | `POST` | [Create a clinic location](/api-reference/clinic-locations/createClinicLocation) | | `DELETE` | [Deactivate a clinic location](/api-reference/clinic-locations/deleteClinicLocation) | | `GET` | [Get a clinic location by ID](/api-reference/clinic-locations/getClinicLocation) | | `GET` | [List clinic locations](/api-reference/clinic-locations/listClinicLocations) | | `PUT` | [Update a clinic location](/api-reference/clinic-locations/updateClinicLocation) | --- # Clinic Payment Methods Documentation: https://docs.guidelab.co/api-reference/clinic-payment-methods ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ---------------------------------------------------------------------------------------------------------- | | `POST` | [Create Clinic Setup Intent](/api-reference/clinic-payment-methods/createClinicSetupIntent) | | `DELETE` | [Delete Clinic Payment Method](/api-reference/clinic-payment-methods/deleteClinicPaymentMethod) | | `POST` | [Enable clinic-owned saved-card autopay](/api-reference/clinic-payment-methods/enableClinicAutopayMandate) | | `GET` | [Get clinic autopay consent](/api-reference/clinic-payment-methods/getClinicAutopayMandate) | | `GET` | [List Clinic Payment Methods](/api-reference/clinic-payment-methods/listClinicPaymentMethods) | | `DELETE` | [Revoke clinic-owned autopay](/api-reference/clinic-payment-methods/revokeClinicAutopayMandate) | | `PUT` | [Set Default Clinic Payment Method](/api-reference/clinic-payment-methods/setDefaultClinicPaymentMethod) | --- # Company Settings Documentation: https://docs.guidelab.co/api-reference/company-settings ## Endpoints [#endpoints] | Method | Endpoint | | -------- | --------------------------------------------------------------------------------------------- | | `DELETE` | [Delete Company Cover Image](/api-reference/company-settings/deleteCompanyCoverImage) | | `DELETE` | [Delete Company Gallery Image](/api-reference/company-settings/deleteCompanyGalleryImage) | | `DELETE` | [Delete Company Logo](/api-reference/company-settings/deleteCompanyLogo) | | `GET` | [Get Company Cover Image](/api-reference/company-settings/getCompanyCoverImage) | | `GET` | [Get Company Gallery Image](/api-reference/company-settings/getCompanyGalleryImage) | | `GET` | [Get Company Logo](/api-reference/company-settings/getCompanyLogo) | | `GET` | [Get Company Settings](/api-reference/company-settings/getCompanySettings) | | `GET` | [List Company Gallery Images](/api-reference/company-settings/listCompanyGalleryImages) | | `POST` | [Reorder Company Gallery Images](/api-reference/company-settings/reorderCompanyGalleryImages) | | `PUT` | [Update Company Settings](/api-reference/company-settings/updateCompanySettings) | | `POST` | [Upload Company Cover Image](/api-reference/company-settings/uploadCompanyCoverImage) | | `POST` | [Upload Company Gallery Image](/api-reference/company-settings/uploadCompanyGalleryImage) | | `POST` | [Upload Company Logo](/api-reference/company-settings/uploadCompanyLogo) | --- # Compliance Documentation: https://docs.guidelab.co/api-reference/compliance ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `GET` | [A document with its latest revision and revision history](/api-reference/compliance/getComplianceDocument) | | `POST` | [Generate a document from its template as a new revision, or start a blank one for an uploaded document type](/api-reference/compliance/generateComplianceDocument) | | `PUT` | [Mark a document type not applicable to the lab, or applicable again](/api-reference/compliance/setComplianceTypeHidden) | | `GET` | [One revision of a document, with its content](/api-reference/compliance/getComplianceRevision) | | `GET` | [Regulatory documents checklist for the lab's country](/api-reference/compliance/getComplianceOverview) | | `POST` | [Restore an earlier revision as the newest one](/api-reference/compliance/restoreComplianceRevision) | | `POST` | [Save the edited document as a new revision](/api-reference/compliance/saveComplianceRevision) | | `PUT` | [Save the lab data shared by compliance documents](/api-reference/compliance/updateComplianceProfile) | | `PUT` | [Set the device family and class of product categories](/api-reference/compliance/updateComplianceClassification) | | `PUT` | [Share a customer-facing document with partner clinics](/api-reference/compliance/shareComplianceDocument) | | `GET` | [The uploaded file of a revision, streamed inline](/api-reference/compliance/getComplianceRevisionFile) | | `POST` | [Upload an issued document as the next revision](/api-reference/compliance/uploadComplianceDocument) | --- # Components Documentation: https://docs.guidelab.co/api-reference/components ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ------------------------------------------------------------------------------ | | `POST` | [Create a component](/api-reference/components/createComponent) | | `DELETE` | [Delete a component](/api-reference/components/deleteComponent) | | `GET` | [Get component settings](/api-reference/components/getComponentSettings) | | `GET` | [List components](/api-reference/components/listComponents) | | `POST` | [Reorder components](/api-reference/components/reorderComponents) | | `PUT` | [Update a component](/api-reference/components/updateComponent) | | `PUT` | [Update component settings](/api-reference/components/updateComponentSettings) | --- # Consolidations Documentation: https://docs.guidelab.co/api-reference/consolidations ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ------------------------------------------------------------------------- | | `POST` | [Create Consolidation](/api-reference/consolidations/createConsolidation) | | `DELETE` | [Delete Consolidation](/api-reference/consolidations/deleteConsolidation) | | `POST` | [Email Consolidation](/api-reference/consolidations/emailConsolidation) | | `GET` | [Get Consolidation](/api-reference/consolidations/getConsolidation) | | `GET` | [List Consolidations](/api-reference/consolidations/listConsolidations) | --- # Conversations Documentation: https://docs.guidelab.co/api-reference/conversations ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ----------------------------------------------------------------------------------------------------------------- | | `POST` | [Approve whole-conversation deletion](/api-reference/conversations/approveConversationDeletion) | | `DELETE` | [Archive a participant-owned conversation attachment](/api-reference/conversations/archiveConversationAttachment) | | `PATCH` | [Assign, snooze, close or mark a thread unread](/api-reference/conversations/updateConversationLabState) | | `POST` | [Create a conversation](/api-reference/conversations/createConversation) | | `GET` | [Download a conversation attachment](/api-reference/conversations/getConversationAttachment) | | `POST` | [Finalize a direct conversation attachment upload](/api-reference/conversations/finalizeConversationAttachment) | | `GET` | [Get conversation by ID](/api-reference/conversations/getConversation) | | `GET` | [List conversations](/api-reference/conversations/listConversations) | | `GET` | [List messages in a conversation](/api-reference/conversations/listConversationMessages) | | `POST` | [Mark conversation as read](/api-reference/conversations/markConversationRead) | | `POST` | [Prepare a direct conversation attachment upload](/api-reference/conversations/presignConversationAttachment) | | `POST` | [Retry a failed channel delivery](/api-reference/conversations/retryConversationMessageDelivery) | | `POST` | [Send a message in a conversation](/api-reference/conversations/sendMessage) | | `POST` | [Transcribe a voice attachment](/api-reference/conversations/transcribeConversationAttachment) | --- # Credit Notes Documentation: https://docs.guidelab.co/api-reference/credit-notes ## Endpoints [#endpoints] | Method | Endpoint | | -------- | -------------------------------------------------------------------------- | | `POST` | [Allocate Credit Note](/api-reference/credit-notes/allocateCreditNote) | | `POST` | [Create Credit Note](/api-reference/credit-notes/createCreditNote) | | `DELETE` | [Deallocate Credit Note](/api-reference/credit-notes/deallocateCreditNote) | | `POST` | [Email Credit Note](/api-reference/credit-notes/emailCreditNote) | | `GET` | [Get Credit Note](/api-reference/credit-notes/getCreditNote) | | `GET` | [List Credit Notes](/api-reference/credit-notes/listCreditNotes) | | `POST` | [Refund Credit Note](/api-reference/credit-notes/refundCreditNote) | | `DELETE` | [Void Credit Note](/api-reference/credit-notes/voidCreditNote) | --- # Dashboard Documentation: https://docs.guidelab.co/api-reference/dashboard ## Endpoints [#endpoints] | Method | Endpoint | | ------ | -------------------------------------------------------------------------------------------------------- | | `GET` | [Bootstrap all lab dashboard panels in one call](/api-reference/dashboard/getLabDashboardOverview) | | `GET` | [Get active orders by deadline](/api-reference/dashboard/getLabDashboardOperations) | | `GET` | [Get exact clinic dashboard counters](/api-reference/dashboard/getClinicDashboardStats) | | `GET` | [Get lab dashboard statistics](/api-reference/dashboard/getLabDashboardStats) | | `GET` | [Get order and revenue trends](/api-reference/dashboard/getLabDashboardTrends) | | `GET` | [Get today's hourly breakdown](/api-reference/dashboard/getLabDashboardToday) | | `GET` | [List clinic actions](/api-reference/dashboard/getClinicDashboardActions) | | `GET` | [List clinic-safe recent order activity](/api-reference/dashboard/getClinicDashboardActivity) | | `GET` | [List orders currently blocked by an active hold](/api-reference/dashboard/getLabDashboardBlockedOrders) | --- # Data Bundle Documentation: https://docs.guidelab.co/api-reference/data-bundle ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ------------------------------------------------------------------------------------------------------------- | | `POST` | [Dry-run an uploaded bundle against the current organization](/api-reference/data-bundle/analyzeDataBundle) | | `POST` | [Export selected domains as a re-importable zip bundle](/api-reference/data-bundle/exportDataBundle) | | `POST` | [Get a presigned PUT URL for uploading a bundle zip](/api-reference/data-bundle/presignDataBundleUpload) | | `POST` | [Import an uploaded bundle into the current organization](/api-reference/data-bundle/executeDataBundleImport) | --- # Document Settings Documentation: https://docs.guidelab.co/api-reference/document-settings ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ---------------------------------------------------------------------------------------- | | `DELETE` | [Delete Document Footer Logo](/api-reference/document-settings/deleteDocumentFooterLogo) | | `GET` | [Get Document Footer Logo](/api-reference/document-settings/getDocumentFooterLogo) | | `GET` | [Get Document Settings](/api-reference/document-settings/getDocumentSettings) | | `PUT` | [Update Document Settings](/api-reference/document-settings/updateDocumentSettings) | | `POST` | [Upload Document Footer Logo](/api-reference/document-settings/uploadDocumentFooterLogo) | --- # Download Documentation: https://docs.guidelab.co/api-reference/download ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ----------------------------------------------------------------------------------------------- | | `GET` | [Check for a signed uploader update](/api-reference/download/checkUploaderUpdate) | | `GET` | [Download a signed uploader update bundle](/api-reference/download/downloadUploaderUpdateAsset) | | `GET` | [Download software installer for a platform](/api-reference/download/downloadSoftwareInstaller) | --- # Email Templates Documentation: https://docs.guidelab.co/api-reference/email-templates ## Endpoints [#endpoints] | Method | Endpoint | | -------- | --------------------------------------------------------------------------- | | `POST` | [Create Email Template](/api-reference/email-templates/createEmailTemplate) | | `DELETE` | [Delete Email Template](/api-reference/email-templates/deleteEmailTemplate) | | `GET` | [Get Email Template](/api-reference/email-templates/getEmailTemplate) | | `GET` | [List Email Templates](/api-reference/email-templates/listEmailTemplates) | | `PUT` | [Update Email Template](/api-reference/email-templates/updateEmailTemplate) | --- # Equipment Documentation: https://docs.guidelab.co/api-reference/equipment ## Endpoints [#endpoints] | Method | Endpoint | | ------ | -------------------------------------------------------------------------------------------------------- | | `POST` | [Add a machine](/api-reference/equipment/createEquipment) | | `GET` | [Maintenance, calibration and safety-check log of a machine](/api-reference/equipment/listEquipmentLogs) | | `POST` | [Record a maintenance, calibration or safety check](/api-reference/equipment/createEquipmentLog) | | `GET` | [The lab's production equipment with next due dates](/api-reference/equipment/listEquipment) | | `PUT` | [Update or retire a machine](/api-reference/equipment/updateEquipment) | --- # Export Documentation: https://docs.guidelab.co/api-reference/export ## Endpoints [#endpoints] | Method | Endpoint | | ------ | --------------------------------------------------------------------- | | `POST` | [Export balance list as CSV](/api-reference/export/exportBalanceList) | | `POST` | [Export clients as CSV](/api-reference/export/exportClients) | | `POST` | [Export price lists as CSV](/api-reference/export/exportPriceLists) | | `POST` | [Export products as CSV](/api-reference/export/exportProducts) | --- # File Requirements Documentation: https://docs.guidelab.co/api-reference/file-requirements ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ----------------------------------------------------------------------------------------------------------- | | `DELETE` | [Archive file requirement](/api-reference/file-requirements/archiveFileRequirement) | | `POST` | [Create file requirement](/api-reference/file-requirements/createFileRequirement) | | `GET` | [Get file requirement](/api-reference/file-requirements/getFileRequirement) | | `GET` | [Get file requirement example image](/api-reference/file-requirements/getFileRequirementExampleImage) | | `GET` | [List file requirements](/api-reference/file-requirements/listFileRequirements) | | `POST` | [Restore file requirement](/api-reference/file-requirements/restoreFileRequirement) | | `PUT` | [Update file requirement](/api-reference/file-requirements/updateFileRequirement) | | `POST` | [Upload file requirement example image](/api-reference/file-requirements/uploadFileRequirementExampleImage) | --- # Files Documentation: https://docs.guidelab.co/api-reference/files ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ------------------------------------------------------------------------ | | `POST` | [Copy files to an order](/api-reference/files/copyFilesToOrder) | | `DELETE` | [Delete a file](/api-reference/files/deleteFile) | | `GET` | [Download a file](/api-reference/files/downloadFile) | | `POST` | [Finalize a direct file upload](/api-reference/files/finalizeFileUpload) | | `POST` | [Get presigned upload URL](/api-reference/files/presignFileUpload) | | `GET` | [List files](/api-reference/files/listFiles) | | `POST` | [Reassign files between orders](/api-reference/files/reassignFiles) | | `POST` | [Upload a file](/api-reference/files/uploadFile) | --- # Finance Settings Documentation: https://docs.guidelab.co/api-reference/finance-settings ## Endpoints [#endpoints] | Method | Endpoint | | ------ | -------------------------------------------------------------------------------- | | `GET` | [Get Finance Settings](/api-reference/finance-settings/getFinanceSettings) | | `PUT` | [Update Finance Settings](/api-reference/finance-settings/updateFinanceSettings) | --- # Finances Documentation: https://docs.guidelab.co/api-reference/finances ## Endpoints [#endpoints] | Method | Endpoint | | -------- | --------------------------------------------------------------------------------------------- | | `POST` | [Create Expense](/api-reference/finances/createExpense) | | `POST` | [Create Expense Category](/api-reference/finances/createExpenseCategory) | | `DELETE` | [Delete Expense](/api-reference/finances/deleteExpense) | | `DELETE` | [Delete Expense Category](/api-reference/finances/deleteExpenseCategory) | | `GET` | [Get Aged Balances](/api-reference/finances/getAgedBalances) | | `GET` | [Get Cashflow](/api-reference/finances/getCashflow) | | `GET` | [Get Finance Account](/api-reference/finances/getFinanceAccount) | | `GET` | [Get Finances Overview](/api-reference/finances/getFinancesOverview) | | `GET` | [Get Stripe Connect Quarantine](/api-reference/finances/getStripeConnectQuarantine) | | `GET` | [Get Stripe External Adjustment](/api-reference/finances/getStripeExternalAdjustment) | | `GET` | [List Expense Categories](/api-reference/finances/listExpenseCategories) | | `GET` | [List Expenses](/api-reference/finances/listExpenses) | | `GET` | [List Finance Accounts](/api-reference/finances/listFinanceAccounts) | | `GET` | [List Stripe Connect Quarantine](/api-reference/finances/listStripeConnectQuarantine) | | `GET` | [List Stripe External Adjustments](/api-reference/finances/listStripeExternalAdjustments) | | `POST` | [Replay Stripe Connect Quarantine](/api-reference/finances/replayStripeConnectQuarantine) | | `POST` | [Resolve Stripe External Adjustment](/api-reference/finances/resolveStripeExternalAdjustment) | | `PATCH` | [Update Expense](/api-reference/finances/updateExpense) | | `PATCH` | [Update Expense Category](/api-reference/finances/updateExpenseCategory) | | `POST` | [Void Expense](/api-reference/finances/voidExpense) | --- # Hold Reasons Documentation: https://docs.guidelab.co/api-reference/hold-reasons ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ---------------------------------------------------------------------- | | `POST` | [Create Hold Reason](/api-reference/hold-reasons/createHoldReason) | | `DELETE` | [Delete Hold Reason](/api-reference/hold-reasons/deleteHoldReason) | | `GET` | [List Hold Reasons](/api-reference/hold-reasons/listHoldReasons) | | `POST` | [Reorder Hold Reasons](/api-reference/hold-reasons/reorderHoldReasons) | | `PUT` | [Update Hold Reason](/api-reference/hold-reasons/updateHoldReason) | --- # Implant Systems Documentation: https://docs.guidelab.co/api-reference/implant-systems ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ------------------------------------------------------------------------------------- | | `POST` | [Create an implant system](/api-reference/implant-systems/createImplantSystem) | | `DELETE` | [Delete an implant system](/api-reference/implant-systems/deleteImplantSystem) | | `GET` | [Get an implant system](/api-reference/implant-systems/getImplantSystem) | | `GET` | [List implant systems](/api-reference/implant-systems/listImplantSystems) | | `POST` | [Load the default implant systems](/api-reference/implant-systems/seedImplantSystems) | | `PUT` | [Update an implant system](/api-reference/implant-systems/updateImplantSystem) | --- # Import Documentation: https://docs.guidelab.co/api-reference/import ## Endpoints [#endpoints] | Method | Endpoint | | -------- | --------------------------------------------------------------------------------- | | `DELETE` | [Delete an import mapping template](/api-reference/import/deleteImportMapping) | | `POST` | [Import balance list from CSV data](/api-reference/import/importBalanceList) | | `POST` | [Import clients from CSV data](/api-reference/import/importClients) | | `POST` | [Import price list items from CSV data](/api-reference/import/importPriceLists) | | `POST` | [Import products from CSV data](/api-reference/import/importProducts) | | `GET` | [List saved import mappings](/api-reference/import/listImportMappings) | | `POST` | [Save an import mapping template](/api-reference/import/createImportMapping) | | `POST` | [Validate import data before importing](/api-reference/import/validateImportData) | --- # Inbox Documentation: https://docs.guidelab.co/api-reference/inbox ## Endpoints [#endpoints] | Method | Endpoint | | ------- | ------------------------------------------------------------------------------------------------------------ | | `PATCH` | [Assign, snooze, close or mark an Unsorted sender unread](/api-reference/inbox/updateUnsortedSenderLabState) | | `GET` | [Download channel media](/api-reference/inbox/getChannelMedia) | | `GET` | [Get an Unsorted sender](/api-reference/inbox/getUnsortedSender) | | `GET` | [List Unsorted senders](/api-reference/inbox/listUnsortedSenders) | | `PUT` | [Map an Unsorted sender to a customer](/api-reference/inbox/mapUnsortedSender) | | `POST` | [Mark an Unsorted sender read](/api-reference/inbox/markUnsortedSenderRead) | | `POST` | [Reply to an Unsorted sender](/api-reference/inbox/replyToUnsortedSender) | | `POST` | [Retry a failed Unsorted reply](/api-reference/inbox/retryUnsortedReplyDelivery) | | `POST` | [Tie an Unsorted sender to a case](/api-reference/inbox/tieUnsortedSender) | --- # API Reference Complete GuideLab REST API reference, generated from OpenAPI. Documentation: https://docs.guidelab.co/api-reference ## Categories [#categories] | Category | Endpoints | | --------------------------------------------------------------------------- | --------: | | [Admin](/api-reference/admin) | 28 | | [Ai](/api-reference/ai) | 1 | | [Archive](/api-reference/archive) | 6 | | [Automations](/api-reference/automations) | 10 | | [Bundles](/api-reference/bundles) | 6 | | [Calendar](/api-reference/calendar) | 8 | | [Categories](/api-reference/categories) | 13 | | [Checkout](/api-reference/checkout) | 4 | | [Clients](/api-reference/clients) | 1 | | [Clinic](/api-reference/clinic) | 1 | | [Clinic Finances](/api-reference/clinic-finances) | 10 | | [Clinic Locations](/api-reference/clinic-locations) | 5 | | [Clinic Payment Methods](/api-reference/clinic-payment-methods) | 7 | | [Company Settings](/api-reference/company-settings) | 13 | | [Compliance](/api-reference/compliance) | 12 | | [Components](/api-reference/components) | 7 | | [Consolidations](/api-reference/consolidations) | 5 | | [Conversations](/api-reference/conversations) | 14 | | [Credit Notes](/api-reference/credit-notes) | 8 | | [Dashboard](/api-reference/dashboard) | 9 | | [Data Bundle](/api-reference/data-bundle) | 4 | | [Document Settings](/api-reference/document-settings) | 5 | | [Download](/api-reference/download) | 3 | | [Email Templates](/api-reference/email-templates) | 5 | | [Equipment](/api-reference/equipment) | 5 | | [Export](/api-reference/export) | 4 | | [File Requirements](/api-reference/file-requirements) | 8 | | [Files](/api-reference/files) | 8 | | [Finance Settings](/api-reference/finance-settings) | 2 | | [Finances](/api-reference/finances) | 20 | | [Hold Reasons](/api-reference/hold-reasons) | 5 | | [Implant Systems](/api-reference/implant-systems) | 6 | | [Import](/api-reference/import) | 8 | | [Inbox](/api-reference/inbox) | 9 | | [Integrations](/api-reference/integrations) | 91 | | [Inventory](/api-reference/inventory) | 38 | | [Invoices](/api-reference/invoices) | 10 | | [Location Routes](/api-reference/location-routes) | 5 | | [Materials](/api-reference/materials) | 8 | | [Notifications](/api-reference/notifications) | 5 | | [Order Filter Presets](/api-reference/order-filter-presets) | 7 | | [Order Tags](/api-reference/order-tags) | 5 | | [Orders](/api-reference/orders) | 64 | | [Organization](/api-reference/organization) | 28 | | [Organization Onboarding](/api-reference/organization-onboarding) | 4 | | [Organization Settings](/api-reference/organization-settings) | 1 | | [Overpayments](/api-reference/overpayments) | 2 | | [Partnership Payment Settings](/api-reference/partnership-payment-settings) | 2 | | [Partnerships](/api-reference/partnerships) | 20 | | [Patients](/api-reference/patients) | 9 | | [Pickup Requests](/api-reference/pickup-requests) | 15 | | [Practice Groups](/api-reference/practice-groups) | 8 | | [Price Lists](/api-reference/price-lists) | 21 | | [Production](/api-reference/production) | 54 | | [Products](/api-reference/products) | 14 | | [Push Subscriptions](/api-reference/push-subscriptions) | 5 | | [Qc Checklist](/api-reference/qc-checklist) | 5 | | [Qc Settings](/api-reference/qc-settings) | 2 | | [Quality Control](/api-reference/quality-control) | 2 | | [Receiving](/api-reference/receiving) | 1 | | [Remake Reasons](/api-reference/remake-reasons) | 5 | | [Reports](/api-reference/reports) | 10 | | [Scan Inbox](/api-reference/scan-inbox) | 7 | | [Scanner Connections](/api-reference/scanner-connections) | 27 | | [Scanner Settings](/api-reference/scanner-settings) | 2 | | [Search](/api-reference/search) | 3 | | [Setup Guide](/api-reference/setup-guide) | 2 | | [Shade Systems](/api-reference/shade-systems) | 9 | | [Shipments](/api-reference/shipments) | 12 | | [Shipping](/api-reference/shipping) | 2 | | [Standards](/api-reference/standards) | 4 | | [Statements](/api-reference/statements) | 4 | | [Sticker Templates](/api-reference/sticker-templates) | 15 | | [Stripe Connect](/api-reference/stripe-connect) | 7 | | [Team](/api-reference/team) | 9 | | [Team Chat](/api-reference/team-chat) | 12 | | [Transactions](/api-reference/transactions) | 1 | | [Treatment Phases](/api-reference/treatment-phases) | 7 | | [Users](/api-reference/users) | 7 | | [Webhooks](/api-reference/webhooks) | 17 | | [Whatsapp Templates](/api-reference/whatsapp-templates) | 13 | | [Work Trays](/api-reference/work-trays) | 5 | --- # Integrations Documentation: https://docs.guidelab.co/api-reference/integrations ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ------------------------------------------------------------------------------------------------------------------------------------ | | `POST` | [Authorize a laboratory Microsoft work account](/api-reference/integrations/authorizeMicrosoft365) | | `GET` | [Complete Facebook Login and offer the granted Pages](/api-reference/integrations/handleMetaMessagingCallback) | | `GET` | [Complete Google consent and start watching the inbox](/api-reference/integrations/handleGmailInboxCallback) | | `GET` | [Complete Microsoft 365 authorization](/api-reference/integrations/handleMicrosoft365OAuthCallback) | | `PUT` | [Configure Microsoft 365 calendar and outgoing email](/api-reference/integrations/updateMicrosoft365Integration) | | `POST` | [Connect a lab-owned carrier account without retaining its credentials](/api-reference/integrations/connectShipEngineCarrier) | | `POST` | [Connect a Telegram bot to the inbox](/api-reference/integrations/connectTelegramBot) | | `POST` | [Connect a WhatsApp number from Meta Embedded Signup](/api-reference/integrations/completeWhatsAppEmbeddedSignup) | | `POST` | [Connect or update Dentally integration](/api-reference/integrations/connectDentally) | | `POST` | [Connect the chosen Page (and its Instagram account)](/api-reference/integrations/selectMetaPage) | | `DELETE` | [Delete exocad integration](/api-reference/integrations/deleteExocadIntegration) | | `DELETE` | [Delete Fatture in Cloud client mapping](/api-reference/integrations/deleteFattureInCloudClientMapping) | | `DELETE` | [Delete Xero contact mapping](/api-reference/integrations/deleteXeroContactMapping) | | `POST` | [Disconnect a WhatsApp number from the inbox](/api-reference/integrations/disconnectWhatsAppConnection) | | `DELETE` | [Disconnect Dentally integration](/api-reference/integrations/disconnectDentally) | | `POST` | [Disconnect Fatture in Cloud integration](/api-reference/integrations/disconnectFattureInCloud) | | `POST` | [Disconnect Messenger and Instagram from the inbox](/api-reference/integrations/disconnectMetaMessaging) | | `POST` | [Disconnect the Gmail inbox channel](/api-reference/integrations/disconnectGmailInbox) | | `POST` | [Disconnect the Telegram bot from the inbox](/api-reference/integrations/disconnectTelegramBot) | | `POST` | [Disconnect Xero integration](/api-reference/integrations/disconnectXero) | | `POST` | [Enable or disable Twilio inbound messages for the inbox](/api-reference/integrations/configureTwilioInbox) | | `POST` | [Finish a WhatsApp connection (optionally with the number's PIN)](/api-reference/integrations/resumeWhatsAppConnection) | | `GET` | [Get a lab financial document's Fatture in Cloud export and SDI status](/api-reference/integrations/getFattureInCloudDocumentStatus) | | `GET` | [Get Ariba integration status and configuration](/api-reference/integrations/getAribaStatus) | | `GET` | [Get Ariba invoice transmission status](/api-reference/integrations/getAribaInvoiceStatus) | | `GET` | [Get Bite Finder integration status](/api-reference/integrations/getBiteFinderStatus) | | `GET` | [Get Dentally connection status](/api-reference/integrations/getDentallyConnection) | | `GET` | [Get exocad integration status and mappings](/api-reference/integrations/getExocadStatus) | | `GET` | [Get Fatture in Cloud integration status](/api-reference/integrations/getFattureInCloudStatus) | | `GET` | [Get HeyGears integration status](/api-reference/integrations/getHeyGearsStatus) | | `GET` | [Get Microsoft 365 connection and sync status](/api-reference/integrations/getMicrosoft365Integration) | | `GET` | [Get ShipStation partner shipping status](/api-reference/integrations/getShipEngineIntegration) | | `GET` | [Get Twilio integration status](/api-reference/integrations/getTwilioStatus) | | `GET` | [Get Xero integration status](/api-reference/integrations/getXeroStatus) | | `GET` | [Handle Fatture in Cloud OAuth callback](/api-reference/integrations/handleFattureInCloudOAuthCallback) | | `GET` | [Handle Xero OAuth callback](/api-reference/integrations/handleXeroOAuthCallback) | | `POST` | [Initiate Fatture in Cloud OAuth authorization](/api-reference/integrations/initiateFattureInCloudOAuth) | | `POST` | [Initiate Xero OAuth authorization](/api-reference/integrations/initiateXeroOAuth) | | `GET` | [List active partner clinics for Ariba selection](/api-reference/integrations/getAribaEligibleClinics) | | `GET` | [List Bite Finder cases for an order](/api-reference/integrations/listBiteFinderCases) | | `GET` | [List Dentally sync logs](/api-reference/integrations/listDentallySyncLogs) | | `GET` | [List Fatture in Cloud client mappings](/api-reference/integrations/listFattureInCloudClientMappings) | | `GET` | [List Fatture in Cloud companies](/api-reference/integrations/listFattureInCloudCompanies) | | `GET` | [List Fatture in Cloud payment accounts](/api-reference/integrations/listFattureInCloudPaymentAccounts) | | `GET` | [List Fatture in Cloud payment methods](/api-reference/integrations/listFattureInCloudPaymentMethods) | | `GET` | [List Fatture in Cloud sync logs](/api-reference/integrations/listFattureInCloudSyncLogs) | | `GET` | [List Fatture in Cloud VAT types](/api-reference/integrations/listFattureInCloudVatTypes) | | `GET` | [List inbox channel connections and which channels can connect](/api-reference/integrations/listInboxChannels) | | `GET` | [List owned Outlook calendars](/api-reference/integrations/listMicrosoft365Calendars) | | `GET` | [List the lab's connected carrier accounts](/api-reference/integrations/listShipEngineCarriers) | | `GET` | [List the Pages granted by a pending Facebook Login](/api-reference/integrations/listPendingMetaPages) | | `GET` | [List Xero accounts](/api-reference/integrations/listXeroAccounts) | | `GET` | [List Xero contact mappings](/api-reference/integrations/listXeroContactMappings) | | `GET` | [List Xero sync logs](/api-reference/integrations/listXeroSyncLogs) | | `GET` | [List Xero tax rates](/api-reference/integrations/listXeroTaxRates) | | `GET` | [Preview Ariba cXML invoice](/api-reference/integrations/previewAribaCxml) | | `POST` | [Provision the lab's ShipStation partner sub-account](/api-reference/integrations/provisionShipEngineIntegration) | | `POST` | [Queue invoice for Ariba](/api-reference/integrations/sendAribaInvoice) | | `GET` | [Read imported exocad design metadata](/api-reference/integrations/getExocadOrderConstructions) | | `POST` | [Reconcile invoice payments to Fatture in Cloud](/api-reference/integrations/syncFattureInCloudPayments) | | `POST` | [Refresh an invoice's SDI status](/api-reference/integrations/refreshFattureInCloudEInvoiceStatus) | | `POST` | [Resume one bounded calendar sync batch](/api-reference/integrations/syncMicrosoft365Calendar) | | `GET` | [Search Fatture in Cloud clients](/api-reference/integrations/searchFattureInCloudClients) | | `GET` | [Search Xero contacts](/api-reference/integrations/searchXeroContacts) | | `POST` | [Select the Fatture in Cloud company](/api-reference/integrations/selectFattureInCloudCompany) | | `POST` | [Select the Xero organisation for a pending authorization](/api-reference/integrations/selectXeroConnection) | | `POST` | [Send a test message via Twilio](/api-reference/integrations/sendTwilioTestMessage) | | `POST` | [Send an invoice to SDI](/api-reference/integrations/sendFattureInCloudEInvoice) | | `POST` | [Send an order to Bite Finder](/api-reference/integrations/createBiteFinderCase) | | `POST` | [Start Facebook Login for Messenger and Instagram](/api-reference/integrations/authorizeMetaMessaging) | | `POST` | [Start Google consent for the Gmail inbox channel](/api-reference/integrations/authorizeGmailInbox) | | `POST` | [Stop synchronization and remove local Microsoft credentials](/api-reference/integrations/disconnectMicrosoft365) | | `POST` | [Sync a credit note to Fatture in Cloud](/api-reference/integrations/syncFattureInCloudCreditNote) | | `POST` | [Sync a payment allocation to Xero](/api-reference/integrations/syncXeroPayment) | | `POST` | [Sync an invoice to Fatture in Cloud](/api-reference/integrations/syncFattureInCloudInvoice) | | `POST` | [Sync an invoice to Xero](/api-reference/integrations/syncXeroInvoice) | | `POST` | [Test Dentally API credentials](/api-reference/integrations/testDentallyConnection) | | `POST` | [Test the Bite Finder connection](/api-reference/integrations/testBiteFinderConnection) | | `POST` | [Test Twilio API credentials](/api-reference/integrations/testTwilioConnection) | | `POST` | [Trigger Dentally patient sync](/api-reference/integrations/triggerDentallySync) | | `PUT` | [Update Ariba integration settings](/api-reference/integrations/updateAribaIntegration) | | `PUT` | [Update Bite Finder integration settings](/api-reference/integrations/updateBiteFinderIntegration) | | `PUT` | [Update exocad integration settings](/api-reference/integrations/updateExocadIntegration) | | `PUT` | [Update exocad material mappings](/api-reference/integrations/updateExocadMaterialMappings) | | `PUT` | [Update exocad reconstruction type mappings](/api-reference/integrations/updateExocadReconstructionMappings) | | `PUT` | [Update Fatture in Cloud integration settings](/api-reference/integrations/updateFattureInCloudSettings) | | `PUT` | [Update HeyGears integration settings](/api-reference/integrations/updateHeyGearsIntegration) | | `PUT` | [Update Twilio integration settings](/api-reference/integrations/updateTwilioIntegration) | | `PUT` | [Update Xero integration settings](/api-reference/integrations/updateXeroSettings) | | `PUT` | [Upsert Fatture in Cloud client mapping](/api-reference/integrations/upsertFattureInCloudClientMapping) | | `PUT` | [Upsert Xero contact mapping](/api-reference/integrations/upsertXeroContactMapping) | --- # Inventory Documentation: https://docs.guidelab.co/api-reference/inventory ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ----------------------------------------------------------------------------------------- | | `DELETE` | [Archive a supplier](/api-reference/inventory/archiveSupplier) | | `DELETE` | [Archive an inventory item](/api-reference/inventory/archiveInventoryItem) | | `POST` | [Cancel a purchase order](/api-reference/inventory/cancelPurchaseOrder) | | `POST` | [Create a purchase order](/api-reference/inventory/createPurchaseOrder) | | `POST` | [Create a stock adjustment](/api-reference/inventory/createStockAdjustment) | | `POST` | [Create a supplier](/api-reference/inventory/createSupplier) | | `POST` | [Create an adjustment reason](/api-reference/inventory/createAdjustmentReason) | | `POST` | [Create an inventory category](/api-reference/inventory/createInventoryCategory) | | `POST` | [Create an inventory item](/api-reference/inventory/createInventoryItem) | | `DELETE` | [Delete a purchase order](/api-reference/inventory/deletePurchaseOrder) | | `DELETE` | [Delete an adjustment reason](/api-reference/inventory/deleteAdjustmentReason) | | `DELETE` | [Delete an inventory category](/api-reference/inventory/deleteInventoryCategory) | | `DELETE` | [Delete an inventory item image](/api-reference/inventory/deleteInventoryItemImage) | | `GET` | [Get a purchase order](/api-reference/inventory/getPurchaseOrder) | | `GET` | [Get a supplier](/api-reference/inventory/getSupplier) | | `GET` | [Get an inventory category](/api-reference/inventory/getInventoryCategory) | | `GET` | [Get an inventory item](/api-reference/inventory/getInventoryItem) | | `GET` | [Get an inventory item image](/api-reference/inventory/getInventoryItemImage) | | `GET` | [Get inventory dashboard statistics](/api-reference/inventory/getInventoryDashboardStats) | | `GET` | [Get inventory settings](/api-reference/inventory/getInventorySettings) | | `GET` | [List adjustment reasons](/api-reference/inventory/listAdjustmentReasons) | | `GET` | [List inventory categories](/api-reference/inventory/listInventoryCategories) | | `GET` | [List inventory items](/api-reference/inventory/listInventoryItems) | | `GET` | [List purchase orders](/api-reference/inventory/listPurchaseOrders) | | `GET` | [List stock adjustments](/api-reference/inventory/listStockAdjustments) | | `GET` | [List suppliers](/api-reference/inventory/listSuppliers) | | `POST` | [Receive purchase order items](/api-reference/inventory/receivePurchaseOrderItems) | | `POST` | [Reorder adjustment reasons](/api-reference/inventory/reorderAdjustmentReasons) | | `POST` | [Reorder inventory categories](/api-reference/inventory/reorderInventoryCategories) | | `POST` | [Seed default adjustment reasons](/api-reference/inventory/seedAdjustmentReasons) | | `POST` | [Seed default inventory categories](/api-reference/inventory/seedInventoryCategories) | | `POST` | [Send a purchase order](/api-reference/inventory/sendPurchaseOrder) | | `PUT` | [Update a supplier](/api-reference/inventory/updateSupplier) | | `PUT` | [Update an adjustment reason](/api-reference/inventory/updateAdjustmentReason) | | `PUT` | [Update an inventory category](/api-reference/inventory/updateInventoryCategory) | | `PUT` | [Update an inventory item](/api-reference/inventory/updateInventoryItem) | | `PUT` | [Update inventory settings](/api-reference/inventory/updateInventorySettings) | | `POST` | [Upload an inventory item image](/api-reference/inventory/uploadInventoryItemImage) | --- # Invoices Documentation: https://docs.guidelab.co/api-reference/invoices ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ----------------------------------------------------------------------------------- | | `POST` | [Archive Invoice](/api-reference/invoices/archiveInvoice) | | `POST` | [Create Invoice](/api-reference/invoices/createInvoice) | | `DELETE` | [Delete Invoice](/api-reference/invoices/deleteInvoice) | | `POST` | [Email Invoice](/api-reference/invoices/emailInvoice) | | `POST` | [Generate Invoices From Orders](/api-reference/invoices/generateInvoicesFromOrders) | | `GET` | [Get Invoice](/api-reference/invoices/getInvoice) | | `GET` | [Get Invoice By Order](/api-reference/invoices/getInvoiceByOrder) | | `GET` | [List Invoices](/api-reference/invoices/listInvoices) | | `POST` | [Record Invoice Payment](/api-reference/invoices/recordInvoicePayment) | | `PUT` | [Update Invoice](/api-reference/invoices/updateInvoice) | --- # Location Routes Documentation: https://docs.guidelab.co/api-reference/location-routes ## Endpoints [#endpoints] | Method | Endpoint | | -------- | --------------------------------------------------------------------------------- | | `POST` | [Create a location route](/api-reference/location-routes/createLocationRoute) | | `DELETE` | [Deactivate a location route](/api-reference/location-routes/deleteLocationRoute) | | `GET` | [Get a location route by ID](/api-reference/location-routes/getLocationRoute) | | `GET` | [List location routes](/api-reference/location-routes/listLocationRoutes) | | `PUT` | [Update a location route](/api-reference/location-routes/updateLocationRoute) | --- # Materials Documentation: https://docs.guidelab.co/api-reference/materials ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ------------------------------------------------------------------- | | `POST` | [Create a material](/api-reference/materials/createMaterial) | | `DELETE` | [Delete a material](/api-reference/materials/deleteMaterial) | | `DELETE` | [Delete material icon](/api-reference/materials/deleteMaterialIcon) | | `GET` | [Get a material](/api-reference/materials/getMaterial) | | `GET` | [Get material icon](/api-reference/materials/getMaterialIcon) | | `GET` | [List materials](/api-reference/materials/listMaterials) | | `PUT` | [Update a material](/api-reference/materials/updateMaterial) | | `POST` | [Upload material icon](/api-reference/materials/uploadMaterialIcon) | --- # Notifications Documentation: https://docs.guidelab.co/api-reference/notifications ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ------------------------------------------------------------------------------------------------------------ | | `GET` | [Get conversation unread count](/api-reference/notifications/getConversationUnreadCount) | | `GET` | [Get notification unread count](/api-reference/notifications/getNotificationUnreadCount) | | `GET` | [List notifications](/api-reference/notifications/listNotifications) | | `POST` | [Mark notifications as read](/api-reference/notifications/markNotificationsRead) | | `POST` | [One-click unsubscribe from notification emails](/api-reference/notifications/unsubscribeNotificationEmails) | --- # Order Filter Presets Documentation: https://docs.guidelab.co/api-reference/order-filter-presets ## Endpoints [#endpoints] | Method | Endpoint | | -------- | --------------------------------------------------------------------------------------------------------- | | `GET` | [Count orders per filter preset](/api-reference/order-filter-presets/getOrderFilterPresetCounts) | | `POST` | [Create an order filter preset](/api-reference/order-filter-presets/createOrderFilterPreset) | | `DELETE` | [Delete an order filter preset](/api-reference/order-filter-presets/deleteOrderFilterPreset) | | `GET` | [List order filter presets](/api-reference/order-filter-presets/listOrderFilterPresets) | | `POST` | [Reorder order filter presets](/api-reference/order-filter-presets/reorderOrderFilterPresets) | | `POST` | [Reset order filter presets to the defaults](/api-reference/order-filter-presets/resetOrderFilterPresets) | | `PUT` | [Update an order filter preset](/api-reference/order-filter-presets/updateOrderFilterPreset) | --- # Order Tags Documentation: https://docs.guidelab.co/api-reference/order-tags ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ------------------------------------------------------------------- | | `POST` | [Create an order tag](/api-reference/order-tags/createOrderTag) | | `DELETE` | [Deactivate an order tag](/api-reference/order-tags/deleteOrderTag) | | `GET` | [Get an order tag](/api-reference/order-tags/getOrderTag) | | `GET` | [List order tags](/api-reference/order-tags/listOrderTags) | | `PUT` | [Update an order tag](/api-reference/order-tags/updateOrderTag) | --- # Orders Documentation: https://docs.guidelab.co/api-reference/orders ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ---------------------------------------------------------------------------------------------------------------------- | | `POST` | [Add component to order](/api-reference/orders/addOrderComponent) | | `POST` | [Add line item to an existing order](/api-reference/orders/addOrderItem) | | `POST` | [Add tag to order](/api-reference/orders/addOrderTag) | | `POST` | [Approve CAD design (clinic only)](/api-reference/orders/approveCadApproval) | | `POST` | [Approve surgical report (clinic only)](/api-reference/orders/approveSurgicalReport) | | `PATCH` | [Assign or unassign a work tray to a stage (lab only)](/api-reference/orders/assignOrderPhaseWorkTray) | | `POST` | [Bulk delete or cancel orders](/api-reference/orders/bulkDeleteOrders) | | `POST` | [Cancel an order with an explicit refund decision](/api-reference/orders/cancelOrderWithRefundChoice) | | `DELETE` | [Cancel order](/api-reference/orders/cancelOrder) | | `PUT` | [Change a submitted order's shipping](/api-reference/orders/updateOrderShipping) | | `DELETE` | [Clear an incorrectly recorded remake link](/api-reference/orders/clearOrderRemake) | | `POST` | [Create draft order](/api-reference/orders/createDraftOrder) | | `DELETE` | [Delete draft order](/api-reference/orders/deleteDraftOrder) | | `GET` | [Find original orders for the same client and active reasons](/api-reference/orders/getOrderRemakeOptions) | | `GET` | [Get an order's revision-aware QC state](/api-reference/orders/getOrderQc) | | `GET` | [Get calendar data](/api-reference/orders/getOrderCalendar) | | `GET` | [Get current CAD design review state](/api-reference/orders/getCurrentCadApproval) | | `GET` | [Get current surgical report review state](/api-reference/orders/getCurrentSurgicalReport) | | `GET` | [Get dispatched orders](/api-reference/orders/getShippedOrders) | | `GET` | [Get filter options for orders](/api-reference/orders/getOrderFilterOptions) | | `GET` | [Get hold requirements for order](/api-reference/orders/getOrderHoldRequirements) | | `GET` | [Get most recent draft order](/api-reference/orders/getMostRecentDraft) | | `GET` | [Get order by ID](/api-reference/orders/getOrderDetail) | | `GET` | [Get order components](/api-reference/orders/getOrderComponents) | | `GET` | [Get order files](/api-reference/orders/getOrderFiles) | | `GET` | [Get order messages](/api-reference/orders/getOrderMessages) | | `GET` | [Get order print data](/api-reference/orders/getOrderPrintData) | | `GET` | [Get order status history](/api-reference/orders/getOrderStatusHistory) | | `GET` | [Get order tags](/api-reference/orders/getOrderTags) | | `GET` | [Get orders for a specific day](/api-reference/orders/getOrderCalendarDay) | | `GET` | [Get orders needing approval](/api-reference/orders/getOrdersNeedingApproval) | | `GET` | [Get replacement order metadata](/api-reference/orders/getOrderRemake) | | `GET` | [Get specific draft order](/api-reference/orders/getDraftById) | | `GET` | [Get subscription status](/api-reference/orders/getOrderSubscription) | | `PATCH` | [Investigate, answer, close or reopen a report](/api-reference/orders/updateOrderIssue) | | `POST` | [Issue a delivery note (DDT) for an order](/api-reference/orders/createOrderDeliveryNote) | | `POST` | [Issue the statement of a completed order, or get the issued one](/api-reference/orders/issueOrderConformityStatement) | | `GET` | [List order delivery notes (DDT)](/api-reference/orders/listOrderDeliveryNotes) | | `GET` | [List orders](/api-reference/orders/listOrders) | | `GET` | [List tasks of an order's current phase](/api-reference/orders/listOrderPhaseTasks) | | `GET` | [Problem reports on an order](/api-reference/orders/listOrderIssues) | | `POST` | [Put order on hold](/api-reference/orders/createOrderHold) | | `GET` | [Quote the shipping options for an order](/api-reference/orders/getOrderShippingOptions) | | `POST` | [Record an immutable QC inspection](/api-reference/orders/completeOrderQc) | | `PUT` | [Record or correct a remake link](/api-reference/orders/recordOrderRemake) | | `DELETE` | [Remove a line item from an existing order](/api-reference/orders/deleteOrderItem) | | `DELETE` | [Remove component from order](/api-reference/orders/removeOrderComponent) | | `DELETE` | [Remove tag from order](/api-reference/orders/removeOrderTag) | | `POST` | [Report a problem with a delivered order](/api-reference/orders/createOrderIssue) | | `POST` | [Request a new CAD design revision (clinic only)](/api-reference/orders/requestCadApprovalChanges) | | `POST` | [Request a new surgical report revision (clinic only)](/api-reference/orders/requestSurgicalReportChanges) | | `POST` | [Request phase advancement (clinic only)](/api-reference/orders/requestOrderPhaseAdvance) | | `POST` | [Review hold requirement](/api-reference/orders/reviewHoldRequirement) | | `POST` | [Submit an existing order draft](/api-reference/orders/submitDraftOrder) | | `POST` | [Submit hold requirement](/api-reference/orders/submitHoldRequirement) | | `POST` | [Subscribe to order](/api-reference/orders/subscribeToOrder) | | `GET` | [The lab's problem reports, newest first](/api-reference/orders/listLabOrderIssues) | | `GET` | [The statement that accompanies a completed order's devices](/api-reference/orders/getOrderConformityStatement) | | `DELETE` | [Unsubscribe from order](/api-reference/orders/unsubscribeFromOrder) | | `PATCH` | [Update a line item on an existing order](/api-reference/orders/updateOrderItem) | | `PATCH` | [Update draft order](/api-reference/orders/updateDraftOrder) | | `PATCH` | [Update order](/api-reference/orders/updateOrder) | | `PATCH` | [Update order status](/api-reference/orders/updateOrderStatus) | | `GET` | [What a new shipment for an order can carry](/api-reference/orders/getOrderShipmentCandidates) | --- # Organization Documentation: https://docs.guidelab.co/api-reference/organization ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ------------------------------------------------------------------------------------------------------------------------- | | `PATCH` | [Approve or reject a join request](/api-reference/organization/processJoinRequest) | | `GET` | [Check organization name availability](/api-reference/organization/checkOrgNameAvailability) | | `GET` | [Check organization slug availability](/api-reference/organization/checkOrgSlugAvailability) | | `POST` | [Create a new organization](/api-reference/organization/createOrganization) | | `POST` | [Create organization billing portal session](/api-reference/organization/createOrganizationBillingPortalSession) | | `POST` | [Generate or rotate the organization's join code](/api-reference/organization/createJoinCode) | | `GET` | [Get an organization by ID](/api-reference/organization/getOrganization) | | `GET` | [Get current organization subscription](/api-reference/organization/getCurrentOrganizationSubscription) | | `GET` | [Get organization closure status](/api-reference/organization/getOrganizationClosureStatus) | | `GET` | [Get public profile of an organization](/api-reference/organization/getOrganizationProfile) | | `GET` | [Get the organization's active join code](/api-reference/organization/getJoinCode) | | `GET` | [List current user's memberships](/api-reference/organization/listMyMemberships) | | `GET` | [List current user's pending join requests](/api-reference/organization/listMyPendingRequests) | | `GET` | [List members of an organization](/api-reference/organization/listOrganizationMembers) | | `GET` | [List organizations by type](/api-reference/organization/listOrganizationsByType) | | `GET` | [List pending join requests](/api-reference/organization/listJoinRequests) | | `GET` | [List retention holds](/api-reference/organization/listOrganizationRetentionHolds) | | `POST` | [Place a retention hold](/api-reference/organization/placeOrganizationRetentionHold) | | `GET` | [Public organization search](/api-reference/organization/publicSearchOrganizations) | | `POST` | [Redeem a join code to join an organization](/api-reference/organization/redeemJoinCode) | | `POST` | [Release a retention hold](/api-reference/organization/releaseOrganizationRetentionHold) | | `POST` | [Request organization closure](/api-reference/organization/requestOrganizationClosure) | | `POST` | [Request to join an organization](/api-reference/organization/createJoinRequest) | | `POST` | [Resend a join request notification](/api-reference/organization/resendJoinRequest) | | `DELETE` | [Revoke the organization's active join code](/api-reference/organization/revokeJoinCode) | | `GET` | [Search organizations](/api-reference/organization/searchOrganizations) | | `GET` | [Search organizations to join](/api-reference/organization/searchOrganizationsToJoin) | | `PUT` | [Update organization subscription storage add-on](/api-reference/organization/updateOrganizationSubscriptionStorageAddOn) | --- # Organization Onboarding Documentation: https://docs.guidelab.co/api-reference/organization-onboarding ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ---------------------------------------------------------------------------------------------------------------------- | | `POST` | [Complete Clinic Organization Onboarding](/api-reference/organization-onboarding/completeClinicOrganizationOnboarding) | | `POST` | [Create Onboarding Subscription Checkout](/api-reference/organization-onboarding/createOnboardingSubscriptionCheckout) | | `GET` | [Get Organization Onboarding](/api-reference/organization-onboarding/getOrganizationOnboarding) | | `PUT` | [Save Organization Onboarding Step](/api-reference/organization-onboarding/saveOrganizationOnboardingStep) | --- # Organization Settings Documentation: https://docs.guidelab.co/api-reference/organization-settings ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ------------------------------------------------------------------------------------------------------------------------ | | `POST` | [Initialize organization settings defaults](/api-reference/organization-settings/initializeOrganizationSettingsDefaults) | --- # Overpayments Documentation: https://docs.guidelab.co/api-reference/overpayments ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ------------------------------------------------------------------- | | `GET` | [List Overpayments](/api-reference/overpayments/listOverpayments) | | `POST` | [Refund Overpayment](/api-reference/overpayments/refundOverpayment) | --- # Partnership Payment Settings Documentation: https://docs.guidelab.co/api-reference/partnership-payment-settings ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ------------------------------------------------------------------------------------------------------------------------- | | `GET` | [Get payment settings for a partnership](/api-reference/partnership-payment-settings/getPartnershipPaymentSettings) | | `PUT` | [Update payment settings for a partnership](/api-reference/partnership-payment-settings/updatePartnershipPaymentSettings) | --- # Partnerships Documentation: https://docs.guidelab.co/api-reference/partnerships ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ------------------------------------------------------------------------------------------------------------------------------------ | | `POST` | [Accept a pending partnership request](/api-reference/partnerships/acceptPartnership) | | `POST` | [Cancel a managed clinic ownership handoff](/api-reference/partnerships/cancelManagedClinicClaim) | | `POST` | [Cancel a pending partnership request](/api-reference/partnerships/cancelPartnership) | | `GET` | [Compliance documents the partner lab shares with this clinic](/api-reference/partnerships/listPartnershipComplianceDocuments) | | `GET` | [Get clinic detail view for a partnership](/api-reference/partnerships/getPartnershipClinicDetail) | | `GET` | [Get partnership detail view](/api-reference/partnerships/getPartnership) | | `GET` | [Get share-all-patients setting](/api-reference/partnerships/getShareAllPatients) | | `POST` | [Invite a new clinic to GuideLab](/api-reference/partnerships/inviteClinic) | | `POST` | [Invite an owner to claim a lab-managed clinic](/api-reference/partnerships/inviteManagedClinicOwner) | | `GET` | [List partnerships for the current organization](/api-reference/partnerships/listPartnerships) | | `POST` | [Reactivate a suspended partnership](/api-reference/partnerships/reactivatePartnership) | | `POST` | [Reject a pending partnership request](/api-reference/partnerships/rejectPartnership) | | `POST` | [Request a partnership with another organization](/api-reference/partnerships/requestPartnership) | | `POST` | [Resend partnership invitation email](/api-reference/partnerships/resendPartnershipInvite) | | `GET` | [Search for potential partners](/api-reference/partnerships/searchPartners) | | `POST` | [Suspend an active partnership](/api-reference/partnerships/suspendPartnership) | | `POST` | [Terminate a partnership](/api-reference/partnerships/terminatePartnership) | | `GET` | [The file of a shared document's latest revision, streamed inline](/api-reference/partnerships/getPartnershipComplianceDocumentFile) | | `GET` | [The latest revision of a document the partner lab shares](/api-reference/partnerships/getPartnershipComplianceDocument) | | `PUT` | [Update share-all-patients setting](/api-reference/partnerships/updateShareAllPatients) | --- # Patients Documentation: https://docs.guidelab.co/api-reference/patients ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ----------------------------------------------------------------------------------- | | `POST` | [Create a new patient](/api-reference/patients/createPatient) | | `DELETE` | [Erase a patient identity](/api-reference/patients/erasePatientIdentity) | | `GET` | [Get a single patient by ID](/api-reference/patients/getPatient) | | `POST` | [Grant lab access to a patient](/api-reference/patients/grantPatientLabAccess) | | `GET` | [List labs with access to a patient](/api-reference/patients/listPatientLabAccess) | | `GET` | [Paginated patient list](/api-reference/patients/listPatients) | | `DELETE` | [Revoke lab access to a patient](/api-reference/patients/revokePatientLabAccess) | | `GET` | [Search patients (autocomplete / combobox)](/api-reference/patients/searchPatients) | | `PUT` | [Update a patient's details](/api-reference/patients/updatePatient) | --- # Pickup Requests Documentation: https://docs.guidelab.co/api-reference/pickup-requests ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ----------------------------------------------------------------------------------------------------------------------- | | `POST` | [Create a pickup form element](/api-reference/pickup-requests/createPickupFormElement) | | `POST` | [Create a pickup request as a partner clinic](/api-reference/pickup-requests/createPickupRequest) | | `DELETE` | [Deactivate a pickup form element](/api-reference/pickup-requests/deletePickupFormElement) | | `PUT` | [Edit a clinic pickup request before it is scheduled](/api-reference/pickup-requests/updateRequestedPickup) | | `GET` | [Get a pickup form element by ID](/api-reference/pickup-requests/getPickupFormElement) | | `GET` | [Get a pickup request and its immutable history](/api-reference/pickup-requests/getPickupRequest) | | `GET` | [Get pickup request settings](/api-reference/pickup-requests/getPickupRequestSettings) | | `GET` | [Get the current pickup form for an active partnership](/api-reference/pickup-requests/getClinicPickupRequestForm) | | `GET` | [List pickup form elements](/api-reference/pickup-requests/listPickupFormElements) | | `GET` | [List pickup requests visible to the current organization](/api-reference/pickup-requests/listPickupRequests) | | `POST` | [Record a pickup attempt](/api-reference/pickup-requests/createPickupAttempt) | | `PUT` | [Reorder pickup form elements](/api-reference/pickup-requests/reorderPickupFormElements) | | `POST` | [Schedule, assign, route, collect, reschedule, or cancel a pickup](/api-reference/pickup-requests/commandPickupRequest) | | `PUT` | [Update a pickup form element](/api-reference/pickup-requests/updatePickupFormElement) | | `PUT` | [Update pickup request settings](/api-reference/pickup-requests/updatePickupRequestSettings) | --- # Practice Groups Documentation: https://docs.guidelab.co/api-reference/practice-groups ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ----------------------------------------------------------------------------------------------------------- | | `POST` | [Assign partnerships to a practice group](/api-reference/practice-groups/assignPracticeGroupPartnerships) | | `POST` | [Create a practice group](/api-reference/practice-groups/createPracticeGroup) | | `DELETE` | [Deactivate a practice group](/api-reference/practice-groups/deletePracticeGroup) | | `GET` | [Get a practice group by ID](/api-reference/practice-groups/getPracticeGroup) | | `GET` | [List partnerships in a practice group](/api-reference/practice-groups/listPracticeGroupPartnerships) | | `GET` | [List practice groups](/api-reference/practice-groups/listPracticeGroups) | | `DELETE` | [Remove a partnership from a practice group](/api-reference/practice-groups/removePracticeGroupPartnership) | | `PUT` | [Update a practice group](/api-reference/practice-groups/updatePracticeGroup) | --- # Price Lists Documentation: https://docs.guidelab.co/api-reference/price-lists ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ------------------------------------------------------------------------------------------------------------------------ | | `POST` | [Archive or restore a price book](/api-reference/price-lists/archivePriceList) | | `PUT` | [Assign a stable price book to a partnership](/api-reference/price-lists/assignPartnershipPriceList) | | `POST` | [Cancel a future publication](/api-reference/price-lists/cancelPriceListVersion) | | `POST` | [Copy a price book's prices into a new book, as a draft to publish](/api-reference/price-lists/duplicatePriceList) | | `POST` | [Create a stable price book](/api-reference/price-lists/createPriceList) | | `POST` | [Create the one editable draft for a price book](/api-reference/price-lists/createPriceListVersion) | | `DELETE` | [Delete a draft bundle rule](/api-reference/price-lists/deletePriceListBundleRule) | | `DELETE` | [Delete a draft product rule](/api-reference/price-lists/deletePriceListProductRule) | | `DELETE` | [Delete a draft shipping type rule](/api-reference/price-lists/deletePriceListShippingTypeRule) | | `GET` | [Get a version with its product and bundle rules](/api-reference/price-lists/getPriceListVersion) | | `GET` | [Get one price book with its versions](/api-reference/price-lists/getPriceList) | | `GET` | [List stable price books and their versions](/api-reference/price-lists/listPriceLists) | | `POST` | [Preview authoritative pricing without pinning an order](/api-reference/price-lists/previewOrderPricing) | | `POST` | [Publish an immutable effective-dated version](/api-reference/price-lists/publishPriceListVersion) | | `PUT` | [Replace the products hidden from this price book's customers](/api-reference/price-lists/updatePriceListHiddenProducts) | | `PUT` | [Set a draft bundle rule](/api-reference/price-lists/upsertPriceListBundleRule) | | `PUT` | [Set a draft product rule](/api-reference/price-lists/upsertPriceListProductRule) | | `PUT` | [Set a draft shipping type rule](/api-reference/price-lists/upsertPriceListShippingTypeRule) | | `POST` | [Shorten an active or future publication](/api-reference/price-lists/endPriceListVersion) | | `PATCH` | [Update draft defaults with optimistic concurrency](/api-reference/price-lists/updatePriceListVersion) | | `PATCH` | [Update stable price-book metadata](/api-reference/price-lists/updatePriceList) | --- # Production Documentation: https://docs.guidelab.co/api-reference/production ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ----------------------------------------------------------------------------------------------------------------- | | `GET` | [Aggregate stats for a printer over a trailing window](/api-reference/production/getPrinterHistoryStats) | | `POST` | [Assign a room to a teammate](/api-reference/production/assignTeammateRoom) | | `POST` | [Bulk update tasks](/api-reference/production/bulkUpdateProductionTasks) | | `DELETE` | [Clear assignment fields for an order phase task](/api-reference/production/clearOrderPhaseTaskAssignment) | | `POST` | [Complete a print batch](/api-reference/production/completePrintBatch) | | `PATCH` | [Correct a closed time entry with an audit reason](/api-reference/production/correctProductionTaskTime) | | `POST` | [Create a print batch](/api-reference/production/createPrintBatch) | | `POST` | [Create a printer](/api-reference/production/createPrinter) | | `POST` | [Create a production room](/api-reference/production/createProductionRoom) | | `POST` | [Create a task](/api-reference/production/createProductionTask) | | `GET` | [Cronologia: list activity rows for an order](/api-reference/production/listOrderActivity) | | `DELETE` | [Delete a print batch](/api-reference/production/deletePrintBatch) | | `DELETE` | [Delete a printer](/api-reference/production/deletePrinter) | | `DELETE` | [Delete a production room](/api-reference/production/deleteProductionRoom) | | `DELETE` | [Delete a task](/api-reference/production/deleteProductionTask) | | `POST` | [Fire a task (runs trigger + side effects, logs activity)](/api-reference/production/fireProductionTask) | | `GET` | [Get a print batch](/api-reference/production/getPrintBatch) | | `GET` | [Get a printer](/api-reference/production/getPrinter) | | `GET` | [Get a production room](/api-reference/production/getProductionRoom) | | `GET` | [Get a task](/api-reference/production/getProductionTask) | | `GET` | [Get lab-internal preferred operators for a customer](/api-reference/production/getCustomerProductionPreferences) | | `GET` | [Get production settings](/api-reference/production/getProductionSettings) | | `GET` | [Get production statistics overview](/api-reference/production/getProductionStatisticsOverview) | | `GET` | [Get task time and timer state](/api-reference/production/getProductionTaskTime) | | `GET` | [Get teammate production settings](/api-reference/production/getTeammateSettings) | | `GET` | [Get teammate room assignments](/api-reference/production/getTeammateRoomAssignments) | | `GET` | [Get the current operator timer across rooms](/api-reference/production/getRunningProductionTaskTime) | | `GET` | [Get the task plan for an order](/api-reference/production/getOrderTaskPlan) | | `GET` | [List completed and failed print batches](/api-reference/production/listPrintBatchHistory) | | `GET` | [List every running operator timer in the lab](/api-reference/production/listLabRunningProductionTimers) | | `GET` | [List orders assigned to a production room](/api-reference/production/listRoomRuntimeOrders) | | `GET` | [List print batches](/api-reference/production/listPrintBatches) | | `GET` | [List printers](/api-reference/production/listPrinters) | | `GET` | [List production rooms](/api-reference/production/listProductionRooms) | | `GET` | [List production tasks](/api-reference/production/listProductionTasks) | | `GET` | [List production teammates](/api-reference/production/listProductionTeammates) | | `POST` | [Mark a print batch as failed](/api-reference/production/failPrintBatch) | | `GET` | [Per-day scheduled-stage counts for a production room](/api-reference/production/getRoomScheduleCounts) | | `GET` | [Read a checklist reference image](/api-reference/production/getTaskChecklistImage) | | `DELETE` | [Remove a teammate room assignment](/api-reference/production/removeTeammateRoomAssignment) | | `PUT` | [Reorder production rooms](/api-reference/production/reorderProductionRooms) | | `PUT` | [Save one customer's preferred operators](/api-reference/production/updateCustomerProductionPreferences) | | `POST` | [Set per-order assignee/date/notes for a task](/api-reference/production/updateOrderPhaseTaskAssignment) | | `POST` | [Start a print batch](/api-reference/production/startPrintBatch) | | `POST` | [Start, pause or resume operator work](/api-reference/production/updateProductionTaskTimer) | | `GET` | [Storico: lab-wide activity feed](/api-reference/production/listProductionActivityFeed) | | `GET` | [Task time, delays and delivery risk](/api-reference/production/getProductionTimeReport) | | `PUT` | [Update a printer](/api-reference/production/updatePrinter) | | `PUT` | [Update a production room](/api-reference/production/updateProductionRoom) | | `PATCH` | [Update a task](/api-reference/production/updateProductionTask) | | `PUT` | [Update production settings](/api-reference/production/updateProductionSettings) | | `PUT` | [Update teammate production settings](/api-reference/production/updateTeammateSettings) | | `PUT` | [Update teammate room permissions](/api-reference/production/updateTeammateRoomPermissions) | | `POST` | [Upload a private checklist reference image](/api-reference/production/uploadTaskChecklistImage) | --- # Products Documentation: https://docs.guidelab.co/api-reference/products ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ------------------------------------------------------------------------------------ | | `POST` | [Create a product](/api-reference/products/createProduct) | | `DELETE` | [Delete a product](/api-reference/products/deleteProduct) | | `DELETE` | [Delete custom field image](/api-reference/products/deleteCustomFieldImage) | | `DELETE` | [Delete product image](/api-reference/products/deleteProductImage) | | `GET` | [Get a product](/api-reference/products/getProduct) | | `GET` | [Get custom field image](/api-reference/products/getCustomFieldImage) | | `GET` | [Get product image](/api-reference/products/getProductImage) | | `GET` | [List product picker options](/api-reference/products/listProductOptions) | | `GET` | [List products](/api-reference/products/listProducts) | | `GET` | [List recent custom field templates](/api-reference/products/listRecentCustomFields) | | `PATCH` | [Partially update a product](/api-reference/products/patchProduct) | | `PUT` | [Update a product](/api-reference/products/updateProduct) | | `POST` | [Upload custom field image](/api-reference/products/uploadCustomFieldImage) | | `POST` | [Upload product image](/api-reference/products/uploadProductImage) | --- # Push Subscriptions Documentation: https://docs.guidelab.co/api-reference/push-subscriptions ## Endpoints [#endpoints] | Method | Endpoint | | -------- | --------------------------------------------------------------------------------------------------- | | `GET` | [Get VAPID public key](/api-reference/push-subscriptions/getVapidPublicKey) | | `GET` | [List push subscriptions](/api-reference/push-subscriptions/listPushSubscriptions) | | `POST` | [Register push subscription](/api-reference/push-subscriptions/registerPushSubscription) | | `PUT` | [Register this device's Expo push token](/api-reference/push-subscriptions/registerNativePushToken) | | `DELETE` | [Unregister push subscription](/api-reference/push-subscriptions/unregisterPushSubscription) | --- # Qc Checklist Documentation: https://docs.guidelab.co/api-reference/qc-checklist ## Endpoints [#endpoints] | Method | Endpoint | | -------- | --------------------------------------------------------------------------------- | | `POST` | [Create Qc Checklist Item](/api-reference/qc-checklist/createQcChecklistItem) | | `DELETE` | [Delete Qc Checklist Item](/api-reference/qc-checklist/deleteQcChecklistItem) | | `GET` | [List Qc Checklist Items](/api-reference/qc-checklist/listQcChecklistItems) | | `POST` | [Reorder Qc Checklist Items](/api-reference/qc-checklist/reorderQcChecklistItems) | | `PUT` | [Update Qc Checklist Item](/api-reference/qc-checklist/updateQcChecklistItem) | --- # Qc Settings Documentation: https://docs.guidelab.co/api-reference/qc-settings ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ----------------------------------------------------------------- | | `GET` | [Get Qc Settings](/api-reference/qc-settings/getQcSettings) | | `PUT` | [Update Qc Settings](/api-reference/qc-settings/updateQcSettings) | --- # Quality Control Documentation: https://docs.guidelab.co/api-reference/quality-control ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ----------------------------------------------------------------------------------- | | `GET` | [Get an order's revision-aware QC state](/api-reference/quality-control/getOrderQc) | | `POST` | [Record an immutable QC inspection](/api-reference/quality-control/completeOrderQc) | --- # Receiving Documentation: https://docs.guidelab.co/api-reference/receiving ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ----------------------------------------------------------------------------- | | `GET` | [List Receiving Categories](/api-reference/receiving/listReceivingCategories) | --- # Remake Reasons Documentation: https://docs.guidelab.co/api-reference/remake-reasons ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ---------------------------------------------------------------------------- | | `POST` | [Create Remake Reason](/api-reference/remake-reasons/createRemakeReason) | | `DELETE` | [Delete Remake Reason](/api-reference/remake-reasons/deleteRemakeReason) | | `GET` | [List Remake Reasons](/api-reference/remake-reasons/listRemakeReasons) | | `POST` | [Reorder Remake Reasons](/api-reference/remake-reasons/reorderRemakeReasons) | | `PUT` | [Update Remake Reason](/api-reference/remake-reasons/updateRemakeReason) | --- # Reports Documentation: https://docs.guidelab.co/api-reference/reports ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ---------------------------------------------------------------------------------- | | `POST` | [Create a custom report](/api-reference/reports/createReport) | | `DELETE` | [Delete a custom report](/api-reference/reports/deleteReport) | | `POST` | [Execute a report query](/api-reference/reports/executeReport) | | `POST` | [Export a report as CSV](/api-reference/reports/exportReport) | | `GET` | [Get a report by ID](/api-reference/reports/getReport) | | `GET` | [List available report data sources](/api-reference/reports/listReportDataSources) | | `GET` | [List reports](/api-reference/reports/listReports) | | `POST` | [Preview an unsaved report](/api-reference/reports/previewReport) | | `GET` | [Report templates and saved reports](/api-reference/reports/getReportCatalog) | | `PATCH` | [Update a report](/api-reference/reports/updateReport) | --- # Scan Inbox Documentation: https://docs.guidelab.co/api-reference/scan-inbox ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ----------------------------------------------------------------------------------------- | | `POST` | [Assign scan inbox item to existing order](/api-reference/scan-inbox/assignScanInboxItem) | | `POST` | [Book scan inbox item as new order](/api-reference/scan-inbox/bookScanInboxItem) | | `POST` | [Bulk action on scan inbox items](/api-reference/scan-inbox/bulkScanInboxAction) | | `POST` | [Dismiss a scan inbox item](/api-reference/scan-inbox/dismissScanInboxItem) | | `GET` | [List scan inbox items](/api-reference/scan-inbox/listScanInboxItems) | | `POST` | [Re-run matching for a scan inbox item](/api-reference/scan-inbox/matchScanInboxItem) | | `POST` | [Sync scan inbox from scanner connections](/api-reference/scan-inbox/syncScanInbox) | --- # Scanner Connections Documentation: https://docs.guidelab.co/api-reference/scanner-connections ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `POST` | [Attach or dismiss the latest confidently matched scanner session](/api-reference/scanner-connections/selectAutomaticScannerSession) | | `POST` | [Create Scanner Connection](/api-reference/scanner-connections/createScannerConnection) | | `DELETE` | [Delete Scanner Connection](/api-reference/scanner-connections/deleteScannerConnection) | | `POST` | [Disconnect Scanner Connection](/api-reference/scanner-connections/disconnectScannerConnection) | | `GET` | [Get a scanner import's progress and files](/api-reference/scanner-connections/getScannerImportJob) | | `GET` | [Get Allied Star Order Prefill](/api-reference/scanner-connections/getAlliedStarOrderPrefill) | | `GET` | [Get Scanner Connection](/api-reference/scanner-connections/getScannerConnection) | | `GET` | [Get Scanner Connection Case](/api-reference/scanner-connections/getScannerConnectionCase) | | `GET` | [Handle Allied Star Authorization Callback](/api-reference/scanner-connections/handleAlliedStarAuthorizationCallback) | | `GET` | [Handle Allied Star Authorization Callback With State](/api-reference/scanner-connections/handleAlliedStarAuthorizationCallbackWithState) | | `GET` | [Handle Itero O Auth Callback](/api-reference/scanner-connections/handleIteroOAuthCallback) | | `GET` | [Handle Medit O Auth Callback](/api-reference/scanner-connections/handleMeditOAuthCallback) | | `GET` | [Handle Shining3d O Auth Callback](/api-reference/scanner-connections/handleShining3dOAuthCallback) | | `GET` | [Handle3 Shape O Auth Callback](/api-reference/scanner-connections/handle3ShapeOAuthCallback) | | `POST` | [Import Scanner Case](/api-reference/scanner-connections/importScannerCase) | | `POST` | [Import Scanner Files](/api-reference/scanner-connections/importScannerFiles) | | `POST` | [Initiate Scanner O Auth](/api-reference/scanner-connections/initiateScannerOAuth) | | `GET` | [List a clinic patient's scanner sessions](/api-reference/scanner-connections/listPatientScannerSessions) | | `GET` | [List Itero Related Accounts](/api-reference/scanner-connections/listIteroRelatedAccounts) | | `GET` | [List Scanner Connection Cases](/api-reference/scanner-connections/listScannerConnectionCases) | | `GET` | [List Scanner Connections](/api-reference/scanner-connections/listScannerConnections) | | `POST` | [Pair Itero Account](/api-reference/scanner-connections/pairIteroAccount) | | `POST` | [Retry a failed scanner import after user action](/api-reference/scanner-connections/retryScannerImportJob) | | `POST` | [Setup Medit Webhook](/api-reference/scanner-connections/setupMeditWebhook) | | `POST` | [Sync Scanner Connection](/api-reference/scanner-connections/syncScannerConnection) | | `POST` | [Test Scanner Connection](/api-reference/scanner-connections/testScannerConnection) | | `PUT` | [Update Scanner Connection](/api-reference/scanner-connections/updateScannerConnection) | --- # Scanner Settings Documentation: https://docs.guidelab.co/api-reference/scanner-settings ## Endpoints [#endpoints] | Method | Endpoint | | ------ | -------------------------------------------------------------------------------- | | `GET` | [Get Scanner Settings](/api-reference/scanner-settings/getScannerSettings) | | `PUT` | [Update Scanner Settings](/api-reference/scanner-settings/updateScannerSettings) | --- # Search Documentation: https://docs.guidelab.co/api-reference/search ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ---------------------------------------------------------------------------------------------- | | `GET` | [Address suggestions for a partial address](/api-reference/search/searchAddresses) | | `GET` | [Global search across all entities](/api-reference/search/searchGlobal) | | `GET` | [Resolve one suggestion into a structured address](/api-reference/search/resolveSearchAddress) | --- # Setup Guide Documentation: https://docs.guidelab.co/api-reference/setup-guide ## Endpoints [#endpoints] | Method | Endpoint | | ------- | --------------------------------------------------------------------- | | `GET` | [Get the setup guide](/api-reference/setup-guide/getSetupGuide) | | `PATCH` | [Update the setup guide](/api-reference/setup-guide/updateSetupGuide) | --- # Shade Systems Documentation: https://docs.guidelab.co/api-reference/shade-systems ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ------------------------------------------------------------------------------ | | `POST` | [Create a shade system](/api-reference/shade-systems/createShadeSystem) | | `DELETE` | [Delete a shade system](/api-reference/shade-systems/deleteShadeSystem) | | `DELETE` | [Delete shade value image](/api-reference/shade-systems/deleteShadeValueImage) | | `GET` | [Get a shade system](/api-reference/shade-systems/getShadeSystem) | | `GET` | [Get shade value image](/api-reference/shade-systems/getShadeValueImage) | | `GET` | [List shade systems](/api-reference/shade-systems/listShadeSystems) | | `PATCH` | [Patch a shade system](/api-reference/shade-systems/patchShadeSystem) | | `PUT` | [Update a shade system](/api-reference/shade-systems/updateShadeSystem) | | `POST` | [Upload shade value image](/api-reference/shade-systems/uploadShadeValueImage) | --- # Shipments Documentation: https://docs.guidelab.co/api-reference/shipments ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ---------------------------------------------------------------------------------------------------------------------- | | `POST` | [Attach a manually purchased carrier label](/api-reference/shipments/createManualShipmentLabel) | | `POST` | [Create a quantity-level outbound shipment](/api-reference/shipments/createShipment) | | `GET` | [Download an authorized immutable carrier-label PDF](/api-reference/shipments/downloadShipmentLabelDocument) | | `GET` | [Get an outbound shipment](/api-reference/shipments/getShipment) | | `GET` | [Get durable provider operation status](/api-reference/shipments/getShipmentProviderOperation) | | `GET` | [List outbound shipments visible to the active organization](/api-reference/shipments/listShipments) | | `POST` | [Purchase a ShipStation label from a signed rate](/api-reference/shipments/purchaseProviderShipmentLabel) | | `POST` | [Quote bounded ShipStation rates for one shipment package](/api-reference/shipments/quoteShipmentPackageRates) | | `POST` | [Record a replay-safe package pack/unpack scan](/api-reference/shipments/recordShipmentScan) | | `POST` | [Transition an outbound shipment](/api-reference/shipments/transitionShipment) | | `POST` | [Void a ShipStation label without repeating the provider mutation](/api-reference/shipments/voidProviderShipmentLabel) | | `POST` | [Void an attached manual carrier label](/api-reference/shipments/voidShipmentLabel) | --- # Shipping Documentation: https://docs.guidelab.co/api-reference/shipping ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ------------------------------------------------------------------------------------------- | | `GET` | [Get the lab's shipping rate table](/api-reference/shipping/getShippingSettings) | | `PUT` | [Save the lab's whole shipping rate table](/api-reference/shipping/replaceShippingSettings) | --- # Standards Documentation: https://docs.guidelab.co/api-reference/standards ## Endpoints [#endpoints] | Method | Endpoint | | ------- | -------------------------------------------------------------------------------- | | `POST` | [Create a quality standard](/api-reference/standards/createStandard) | | `GET` | [List quality standards](/api-reference/standards/listStandards) | | `PATCH` | [Toggle quality standard active status](/api-reference/standards/toggleStandard) | | `PUT` | [Update a quality standard](/api-reference/standards/updateStandard) | --- # Statements Documentation: https://docs.guidelab.co/api-reference/statements ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ----------------------------------------------------------------- | | `POST` | [Email Statement](/api-reference/statements/emailStatement) | | `POST` | [Generate Statement](/api-reference/statements/generateStatement) | | `GET` | [Get Statement](/api-reference/statements/getStatement) | | `GET` | [List Statements](/api-reference/statements/listStatements) | --- # Sticker Templates Documentation: https://docs.guidelab.co/api-reference/sticker-templates ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ----------------------------------------------------------------------------------------------------------- | | `POST` | [Create Sticker Template](/api-reference/sticker-templates/createStickerTemplate) | | `POST` | [Create Sticker Template Category](/api-reference/sticker-templates/createStickerTemplateCategory) | | `DELETE` | [Delete Sticker Template](/api-reference/sticker-templates/deleteStickerTemplate) | | `DELETE` | [Delete Sticker Template Category](/api-reference/sticker-templates/deleteStickerTemplateCategory) | | `DELETE` | [Delete Sticker Template Preview Image](/api-reference/sticker-templates/deleteStickerTemplatePreviewImage) | | `POST` | [Generate Sticker Pdf](/api-reference/sticker-templates/generateStickerPdf) | | `GET` | [Get Sticker Template](/api-reference/sticker-templates/getStickerTemplate) | | `GET` | [Get Sticker Template Category](/api-reference/sticker-templates/getStickerTemplateCategory) | | `GET` | [Get Sticker Template Preview Image](/api-reference/sticker-templates/getStickerTemplatePreviewImage) | | `GET` | [List Sticker Template Categories](/api-reference/sticker-templates/listStickerTemplateCategories) | | `GET` | [List Sticker Templates](/api-reference/sticker-templates/listStickerTemplates) | | `GET` | [Preview Sticker Template](/api-reference/sticker-templates/previewStickerTemplate) | | `PUT` | [Update Sticker Template](/api-reference/sticker-templates/updateStickerTemplate) | | `PUT` | [Update Sticker Template Category](/api-reference/sticker-templates/updateStickerTemplateCategory) | | `POST` | [Upload Sticker Template Preview Image](/api-reference/sticker-templates/uploadStickerTemplatePreviewImage) | --- # Stripe Connect Documentation: https://docs.guidelab.co/api-reference/stripe-connect ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ------------------------------------------------------------------------------------------------------- | | `POST` | [Disconnect Stripe Connect](/api-reference/stripe-connect/disconnectStripeConnect) | | `GET` | [Get Stripe Connect Dashboard Link](/api-reference/stripe-connect/getStripeConnectDashboardLink) | | `GET` | [Get Stripe Connect Status](/api-reference/stripe-connect/getStripeConnectStatus) | | `GET` | [Handle Stripe Connect O Auth Callback](/api-reference/stripe-connect/handleStripeConnectOAuthCallback) | | `POST` | [Onboard Stripe Connect](/api-reference/stripe-connect/onboardStripeConnect) | | `POST` | [Refresh Stripe Connect Status](/api-reference/stripe-connect/refreshStripeConnectStatus) | | `POST` | [Start Stripe Connect O Auth](/api-reference/stripe-connect/startStripeConnectOAuth) | --- # Team Documentation: https://docs.guidelab.co/api-reference/team ## Endpoints [#endpoints] | Method | Endpoint | | -------- | -------------------------------------------------------------------------------------- | | `POST` | [Cancel a pending invitation](/api-reference/team/cancelTeamInvitation) | | `POST` | [Create and send team invitation](/api-reference/team/createTeamInvitation) | | `GET` | [List pending invitations](/api-reference/team/listPendingInvitations) | | `GET` | [List team members](/api-reference/team/listTeamMembers) | | `DELETE` | [Remove team member](/api-reference/team/removeTeamMember) | | `POST` | [Resend a pending invitation](/api-reference/team/resendTeamInvitation) | | `POST` | [Send password reset email to team member](/api-reference/team/sendPasswordResetEmail) | | `POST` | [Transfer organization ownership](/api-reference/team/transferOrganizationOwnership) | | `PATCH` | [Update team member role](/api-reference/team/updateTeamMemberRole) | --- # Team Chat Documentation: https://docs.guidelab.co/api-reference/team-chat ## Endpoints [#endpoints] | Method | Endpoint | | -------- | --------------------------------------------------------------------------------------------- | | `POST` | [Add members to a team chat group](/api-reference/team-chat/addTeamChatThreadMembers) | | `GET` | [Count unread team chat messages](/api-reference/team-chat/getTeamChatUnreadCount) | | `GET` | [Download a team chat attachment](/api-reference/team-chat/getTeamChatAttachment) | | `POST` | [Finalize a team chat attachment upload](/api-reference/team-chat/finalizeTeamChatAttachment) | | `GET` | [Get a team chat thread](/api-reference/team-chat/getTeamChatThread) | | `GET` | [List team chat messages](/api-reference/team-chat/listTeamChatMessages) | | `GET` | [List team chat threads](/api-reference/team-chat/listTeamChatThreads) | | `POST` | [Mark a team chat thread read](/api-reference/team-chat/markTeamChatThreadRead) | | `POST` | [Open a direct thread or create a group](/api-reference/team-chat/createTeamChatThread) | | `POST` | [Prepare a team chat attachment upload](/api-reference/team-chat/presignTeamChatAttachment) | | `DELETE` | [Remove a member from a team chat group](/api-reference/team-chat/removeTeamChatThreadMember) | | `POST` | [Send a team chat message](/api-reference/team-chat/sendTeamChatMessage) | --- # Transactions Documentation: https://docs.guidelab.co/api-reference/transactions ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ----------------------------------------------------------------- | | `GET` | [List Transactions](/api-reference/transactions/listTransactions) | --- # Treatment Phases Documentation: https://docs.guidelab.co/api-reference/treatment-phases ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ------------------------------------------------------------------------------------------- | | `POST` | [Create a treatment phase](/api-reference/treatment-phases/createTreatmentPhase) | | `DELETE` | [Delete a treatment phase](/api-reference/treatment-phases/deleteTreatmentPhase) | | `GET` | [Get a treatment phase](/api-reference/treatment-phases/getTreatmentPhase) | | `GET` | [List treatment phases](/api-reference/treatment-phases/listTreatmentPhases) | | `POST` | [Reorder tasks within a treatment phase](/api-reference/treatment-phases/reorderPhaseTasks) | | `POST` | [Reorder treatment phases](/api-reference/treatment-phases/reorderTreatmentPhases) | | `PUT` | [Update a treatment phase](/api-reference/treatment-phases/updateTreatmentPhase) | --- # Users Documentation: https://docs.guidelab.co/api-reference/users ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ----------------------------------------------------------------------------------------- | | `GET` | [Get notification preferences](/api-reference/users/getUserNotificationPreferences) | | `DELETE` | [Remove a user avatar](/api-reference/users/deleteUserAvatar) | | `GET` | [Serve a user avatar](/api-reference/users/getUserAvatar) | | `PUT` | [Update current user language preference](/api-reference/users/updateUserLanguage) | | `PUT` | [Update current user phone number](/api-reference/users/updateUserPhone) | | `PUT` | [Update notification preferences](/api-reference/users/updateUserNotificationPreferences) | | `POST` | [Upload a user avatar](/api-reference/users/uploadUserAvatar) | --- # Webhooks Documentation: https://docs.guidelab.co/api-reference/webhooks ## Endpoints [#endpoints] | Method | Endpoint | | ------ | ----------------------------------------------------------------------------------------------------------------- | | `GET` | [Answer the Meta webhook verification handshake](/api-reference/webhooks/verifyWhatsAppWebhook) | | `GET` | [Answer the Meta webhook verification handshake](/api-reference/webhooks/verifyMetaMessagingWebhook) | | `POST` | [Handle Alliedstar scan-result and order notifications](/api-reference/webhooks/handleAlliedStarWebhook) | | `POST` | [Handle iTero scan notifications](/api-reference/webhooks/handleIteroWebhook) | | `POST` | [Handle Medit events for one scanner connection](/api-reference/webhooks/handleMeditConnectionWebhook) | | `POST` | [Handle Medit scanner webhook events](/api-reference/webhooks/handleMeditWebhook) | | `POST` | [Handle ShipEngine tracking webhook events](/api-reference/webhooks/handleShipEngineTrackingWebhook) | | `POST` | [Handle Stripe Connect webhook events](/api-reference/webhooks/handleStripeConnectWebhook) | | `POST` | [Receive Gmail mailbox change pushes](/api-reference/webhooks/handleGmailPubSubPush) | | `POST` | [Receive inbound Twilio SMS and WhatsApp messages](/api-reference/webhooks/handleTwilioChannelWebhook) | | `POST` | [Receive Messenger and Instagram events](/api-reference/webhooks/handleMetaMessagingWebhook) | | `POST` | [Receive Outlook inbox change notifications](/api-reference/webhooks/handleOutlookMailboxNotification) | | `POST` | [Receive Outlook subscription lifecycle notifications](/api-reference/webhooks/handleOutlookMailboxLifecycle) | | `POST` | [Receive Telegram bot updates](/api-reference/webhooks/handleTelegramChannelWebhook) | | `POST` | [Receive Twilio delivery status callbacks](/api-reference/webhooks/handleTwilioChannelStatusWebhook) | | `POST` | [Receive WhatsApp Cloud API events](/api-reference/webhooks/handleWhatsAppWebhook) | | `GET` | [Serve one outbound attachment to a messaging provider](/api-reference/webhooks/getSignedChannelMediaForProvider) | --- # Whatsapp Templates Documentation: https://docs.guidelab.co/api-reference/whatsapp-templates ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ----------------------------------------------------------------------------------------------------------------- | | `POST` | [Create Whats App Template](/api-reference/whatsapp-templates/createWhatsAppTemplate) | | `DELETE` | [Delete Whats App Template](/api-reference/whatsapp-templates/deleteWhatsAppTemplate) | | `DELETE` | [Delete Whats App Template Event Override](/api-reference/whatsapp-templates/deleteWhatsAppTemplateEventOverride) | | `GET` | [Get Whats App Template](/api-reference/whatsapp-templates/getWhatsAppTemplate) | | `GET` | [List Whats App Template Event Candidates](/api-reference/whatsapp-templates/listWhatsAppTemplateEventCandidates) | | `GET` | [List Whats App Template Event Overrides](/api-reference/whatsapp-templates/listWhatsAppTemplateEventOverrides) | | `GET` | [List Whats App Templates](/api-reference/whatsapp-templates/listWhatsAppTemplates) | | `POST` | [Register Whats App Template](/api-reference/whatsapp-templates/registerWhatsAppTemplate) | | `PUT` | [Set Whats App Template Event Override](/api-reference/whatsapp-templates/setWhatsAppTemplateEventOverride) | | `POST` | [Sync All Whats App Templates](/api-reference/whatsapp-templates/syncAllWhatsAppTemplates) | | `POST` | [Sync Whats App Template](/api-reference/whatsapp-templates/syncWhatsAppTemplate) | | `POST` | [Test Whats App Template](/api-reference/whatsapp-templates/testWhatsAppTemplate) | | `PUT` | [Update Whats App Template](/api-reference/whatsapp-templates/updateWhatsAppTemplate) | --- # Work Trays Documentation: https://docs.guidelab.co/api-reference/work-trays ## Endpoints [#endpoints] | Method | Endpoint | | -------- | ------------------------------------------------------------------------- | | `POST` | [Batch Create Work Trays](/api-reference/work-trays/batchCreateWorkTrays) | | `POST` | [Create Work Tray](/api-reference/work-trays/createWorkTray) | | `DELETE` | [Delete Work Tray](/api-reference/work-trays/deleteWorkTray) | | `GET` | [List Work Trays](/api-reference/work-trays/listWorkTrays) | | `PUT` | [Update Work Tray](/api-reference/work-trays/updateWorkTray) | --- # Authentication How requests to the GuideLab API are authenticated. Documentation: https://docs.guidelab.co/authentication Almost every GuideLab endpoint requires an authenticated request. The API accepts two authentication schemes; pick whichever fits your client. ## Session cookie (web app) [#session-cookie-web-app] The GuideLab web app authenticates with [Better Auth](https://www.better-auth.com). After signing in, the browser holds a session cookie named **`__Secure-guidelab-prod.session_token`**, which is sent automatically with every request to `api.guidelab.co`. This is the scheme used by the first‑party web app — you generally don't manage it yourself; it is set by the sign‑in flow and refreshed by the auth layer. ```http GET /orders HTTP/1.1 Host: api.guidelab.co Cookie: __Secure-guidelab-prod.session_token= ``` ## Native device credential (desktop / programmatic clients) [#native-device-credential-desktop--programmatic-clients] Non-browser clients authenticate with a versioned GuideLab device credential issued by `POST /auth/device/v1/sign-in`. Send that credential in the `Authorization` header. Better Auth browser session tokens are cookie-only and are not accepted as bearer credentials. ```http GET /orders HTTP/1.1 Host: api.guidelab.co Authorization: Bearer gl_device_v1_ ``` ```bash curl "https://api.guidelab.co/orders" \ -H "Authorization: Bearer gl_device_v1_" ``` Cookie sessions and device credentials resolve to the same user and organization authorization context. `bearerAuth` in the OpenAPI document means this versioned device credential, not a Better Auth session token. ## Organization context [#organization-context] GuideLab is multi‑tenant. An authenticated session is bound to a single **organization** (a lab or a clinic) and a **role** within it (`owner` or `staff`). Endpoints automatically operate on that organization's data, and some are restricted: * **By organization type** — e.g. lab‑only or clinic‑only endpoints. * **By role** — e.g. owner‑only settings endpoints. A request that is authenticated but lacks the required type or role receives a [`403`](/errors) response. ## Unauthenticated requests [#unauthenticated-requests] Requests without a valid session cookie or native device credential receive a [`401 Unauthorized`](/errors). A small number of endpoints (such as inbound [webhooks](/webhooks) and health checks) are public and do not require authentication. --- # Errors Error response format and the status codes the API returns. Documentation: https://docs.guidelab.co/errors The GuideLab API uses conventional HTTP status codes to indicate the result of a request, and returns a consistent JSON envelope for failures. ## Error envelope [#error-envelope] Errors respond with a JSON body containing an `error` message and, optionally, a machine-readable `code` and a `details` field with structured context (for example, field‑level validation issues): ```json { "error": "Invalid query parameters", "details": { "limit": "Expected number, received string" } } ``` | Field | Type | Description | | --------- | ------- | ----------------------------------------------------- | | `error` | string | Human‑readable description of what went wrong. | | `code` | string? | Stable identifier for a failure a client can act on. | | `details` | any? | Optional structured details (e.g. validation errors). | Branch on `code`, never on the `error` text, which may change. For example, a shipment command sent with an outdated `expectedVersion` fails with `409` and `"code": "shipment_version_stale"`: reload the shipment and retry. ## Status codes [#status-codes] | Status | Meaning | | ------ | ---------------------------------------------------------------------- | | `200` | **OK** — the request succeeded. | | `201` | **Created** — a new resource was created. | | `400` | **Bad Request** — invalid input (failed validation, malformed body). | | `401` | **Unauthorized** — invalid session or native device credential. | | `403` | **Forbidden** — authenticated, but lacking the required org type/role. | | `404` | **Not Found** — the resource does not exist or isn't in your org. | | `409` | **Conflict** — the request conflicts with current state. | | `500` | **Internal Server Error** — an unexpected error occurred. | A `401` means the request wasn't authenticated — see [Authentication](/authentication). A `403` means it **was** authenticated but the session's organization type or role isn't permitted for that endpoint. ## Validation errors [#validation-errors] Request bodies and query parameters are validated with [Zod](https://zod.dev). When validation fails, the API responds with `400` and includes the offending fields in `details` so clients can surface precise messages. --- # Clinic calendar Use the clinic calendar to review scheduled cases and date-based workload. Documentation: https://docs.guidelab.co/guides/clinic/calendar The clinic calendar provides a date-based view of order activity. It complements the order list: use the calendar to understand *when* work is due and the list to inspect the full case state. ![The clinic calendar](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-calendar.png) ## Use the calendar [#use-the-calendar] 1. move to the day, week, or period you need; 2. identify orders or milestones on that date; 3. open the case to confirm the requested date, current state, and laboratory; 4. resolve conflicts in the order rather than treating the calendar as a second source of truth. The lab's working calendar influences suggested delivery dates during order creation. Bank holidays, lab closure dates, weekends, cutoff time, buffer days, and configured production duration can all affect the earliest realistic date. Changing the clinic calendar view does not reschedule an order. Open the order and use its permitted date controls or contact the laboratory. --- # Files and scanners Manage clinic files, scanner connections, Scanner Explorer, and order attachments. Documentation: https://docs.guidelab.co/guides/clinic/files-and-scanners GuideLab separates the clinic-wide file library from scanner-provider case browsing and the files attached to an individual order. ![The clinic file library](https://assets.guidelab.co/docs/guides/2026-08-16/settings-clinic-uploaded-files.png) ## Uploaded Files [#uploaded-files] The file library can be filtered by scans, photos, documents, X-rays, and other files. Uploading here makes a file available to the clinic; attaching it to an order is a separate step. ## Scanner settings and Scanner Explorer [#scanner-settings-and-scanner-explorer] ![Scanner Explorer before a connection is added](https://assets.guidelab.co/docs/guides/2026-08-16/settings-clinic-scanner-explorer.png) Use **Settings → Scanner** to add and manage supported intraoral scanner connections. **Scanner Explorer** then browses cases exposed by those provider APIs. From an order, use the scanner import flow to choose a case and import the required files. ## Safe matching sequence [#safe-matching-sequence] 1. confirm the scanner account and originating practice; 2. match the provider case to the correct patient; 3. inspect the file names and types; 4. attach only the relevant files to the intended order; 5. resolve duplicate submissions before the laboratory begins work. Scanner integrations are managed separately from the clinic's Dentally integration, which synchronizes patient data. --- # Clinic finances Review balances, laboratory invoices, credit notes, statements, and payment methods. Documentation: https://docs.guidelab.co/guides/clinic/finances Clinic finance consolidates the commercial records received from connected laboratories. The summary shows outstanding balance, unpaid and overdue invoice counts, and the number of labs that have billed the clinic. ![Clinic invoice register](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-finance-invoices.png) ## Tabs [#tabs] * **Invoices** shows laboratory, status, total, outstanding amount, issue date, and due date. Open a row for line items and available payment actions. * **Credit Notes** shows issued credit and the amount still available. * **Statements** groups opening balance, activity, closing balance, and total due for a laboratory and period. ![Clinic credit notes](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-finance-credit-notes.png) ![Clinic statements](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-finance-statements.png) ## Saved payment methods [#saved-payment-methods] **Settings → Billing** manages payment methods separately for each connected lab. When the lab allows it, the clinic can enable saved-card autopay attempts on the due date and again after 3 and 7 days while the invoice remains unpaid. See [Clinic finance reference](/guides/finance/clinic-finance) for payment and reconciliation guidance. --- # Clinic inventory Track clinic stock, suppliers, purchase orders, categories, and adjustment reasons. Documentation: https://docs.guidelab.co/guides/clinic/inventory Clinic inventory uses the same stock model as laboratory inventory, but its categories and defaults are scoped to the clinic. ![The clinic inventory workspace](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-inventory.png?v=20260816) ## Core records [#core-records] * **Items** hold SKU, category, supplier, quantity, limits, cost, location, lot, expiry, and notes. * **Suppliers** hold purchasing and contact details. * **Purchase Orders** group replenishment lines for one supplier. * **Stock movements** record additions and removals with a reason. ## Clinic inventory settings [#clinic-inventory-settings] ![Clinic inventory settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-clinic-inventory-settings.png) * **Low Stock Alerts** shows attention items below their minimum quantity. * **Expiration Alert Days** determines how early expiring stock is highlighted. * **Auto-deduct on Order Completion** consumes configured product material requirements when an order completes. * **Categories** organize items; clinic defaults include clinical consumable groups. * **Adjustment Reasons** make manual additions, removals, damage, expiry, corrections, stocktakes, and returns auditable. For the item and purchasing workflows, see [Inventory overview](/guides/inventory/overview), [Suppliers and items](/guides/inventory/suppliers-and-items), and [Purchase orders](/guides/inventory/purchase-orders). --- # Labs and orders Connect a clinic to a lab, prepare the first order, and manage drafts. Documentation: https://docs.guidelab.co/guides/clinic/labs-and-orders A clinic must be connected to a laboratory before it can send a case. The lab accepts the partnership request, after which the clinic can grant patient access and prepare an order. ### Find a laboratory [#find-a-laboratory] Open **Settings**, go to the lab connection area, and search for the laboratory by name. Review the result before sending a partnership request. ![Finding laboratories from a clinic](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-find-labs.png) ### Send and confirm the partnership [#send-and-confirm-the-partnership] Send the request. It remains pending until the laboratory accepts it. Once accepted, the clinic can share the relevant patient record with that lab. ![A clinic partnership request awaiting acceptance](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-partnership-requested.png) ### Prepare the order [#prepare-the-order] Click **New order** and complete the wizard: 1. select the laboratory and reference doctor; 2. select an existing patient or create a new patient; 3. choose the work type, catalog products, options, materials, and notes; 4. attach required files, reuse patient files, or import from a connected scanner; 5. review the case, requested date, instructions, and authorization, and choose the **Shipping** option; 6. complete payment when the partnership policy requires advance payment. **Shipping:** when the laboratory charges for shipping, the review step lists each shipping type with its price for your address and the order's weight. * Choose one to send the order. * Add insurance when the type offers it. * To send the work together with an open order of yours that is due no earlier, choose **Ship with** that order. You then pay only what the combined weight adds. The shipping price is fixed when you send or pay for the order. It is never discounted and appears as its own line on the invoice. ### Resume a draft [#resume-a-draft] GuideLab saves unfinished work as a draft. Open **Orders** and choose **Continue editing** to resume it. ![A clinic order list with a saved draft](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-orders.png) ## File and due-date behavior [#file-and-due-date-behavior] The selected products determine which files are required. Unsupported uploads are rejected; DICOM groups can be bundled during upload. Some products may be started immediately, while others remain on hold until required information is available. The requested completion date is evaluated against the lab's working calendar, cutoff time, and production lead time. ## Clinic order states [#clinic-order-states] | State | Meaning | | ----------- | ---------------------------------------------------------------- | | Draft | Not submitted; editable from the clinic order list | | Submitted | Sent to the lab and awaiting acceptance or approval | | In Progress | Accepted and moving through production | | On Hold | Work is paused pending information, files, or another resolution | | Completed | Laboratory work is complete | | Cancelled | Closed without completion | Use filters and saved presets to find cases by status, partner, doctor, patient, file state, due date, and other available criteria. The first step requires an eligible reference doctor. If the selector is empty, invite the clinician to the clinic and assign the required clinical role before continuing. --- # Clinic overview Understand the clinic dashboard, navigation, calendar, and setup entry points. Documentation: https://docs.guidelab.co/guides/clinic/overview The clinic workspace keeps patient records, lab connections, orders, messages, inventory, and finances together. Use **New order** for the main clinical workflow and **Settings** for organization-level configuration. ![The clinic dashboard](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-dashboard.png) ## Main areas [#main-areas] * **Dashboard** summarizes current work and activity. * **Orders** contains drafts and submitted cases. * **Calendar** displays dated clinic work. * **Patients** stores the patient record used by orders. * **Inbox** holds conversations with connected laboratories. * **Inventory** and **Finances** support clinic operations. * **Settings** holds organization, team, location, billing, and integration configuration. ## What the dashboard tells you [#what-the-dashboard-tells-you] The clinic dashboard is an exception-oriented summary rather than the full record. Use it to spot order activity and financial attention items, then open the relevant module for the underlying rows. Counts and amounts are scoped to the active clinic. The top search finds orders or patients without leaving the current workspace. The notification bell shows events for the signed-in user; notification channel preferences live in [Personal account settings](/guides/getting-started/personal-account). ![The clinic calendar](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-calendar.png) Use the organization switcher to confirm you are in the correct clinic before creating patient or order data. ## Recommended daily sequence [#recommended-daily-sequence] 1. review the dashboard for exceptions; 2. check **Orders** for drafts, approvals, holds, and due work; 3. review the **Calendar** for date-specific workload; 4. answer new **Inbox** conversations; 5. check inventory or unpaid finance items that need action. Next: [Add and manage patients](/guides/clinic/patients). --- # Patients Add a patient, review the patient list, and open the patient record. Documentation: https://docs.guidelab.co/guides/clinic/patients Every clinic order starts with a patient. Patient records can contain contact details, date of birth, an external identifier, notes, and linked order history. ## Patient fields [#patient-fields] | Field | Purpose | | ------------------- | -------------------------------------------------------------- | | First and last name | Required identity used in searches and orders | | Date of birth | Helps distinguish people with similar names | | Email and phone | Contact information; store only when permitted | | External ID | Link back to the clinic's practice-management system | | Notes | Concise operational context that belongs on the patient record | ### Open the patient form [#open-the-patient-form] Go to **Patients** and click **Add Patient**. ![The add patient form](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-add-patient.png) ### Enter the patient details [#enter-the-patient-details] Complete the required name fields, then add only the contact and reference data your team is permitted to store. Use the external ID to match a record from another practice system. ### Save and review [#save-and-review] The new patient appears in **Patient Records**. Use the row menu for available actions or click the patient name to open the record. ![A populated patient list](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-patients.png) ![The patient detail page](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-patient-detail.png) The patient page is the best place to confirm identity and review order history before starting another case. ## Files, privacy, and lab access [#files-privacy-and-lab-access] * Patient files can be reused in later orders from the file step. * The order wizard can hide patient details from the lab when that option is available and appropriate. * A connected lab sees patient information only after the clinic grants access. * Do not create a duplicate patient when an external ID or existing record can be matched. * Use the archive workflow instead of deleting records that must remain linked to clinical or financial history. Next: [Connect to a lab and create an order](/guides/clinic/labs-and-orders). --- # Inbox Use clinic and laboratory inboxes for case-related communication. Documentation: https://docs.guidelab.co/guides/communications/inbox The **Inbox** keeps organization conversations inside the relevant clinic or laboratory workspace. Use it for operational discussion connected to clients, patients, and orders. ![The laboratory inbox](https://assets.guidelab.co/docs/guides/2026-08-16/lab-inbox.png) ## Start and manage a conversation [#start-and-manage-a-conversation] 1. open **Inbox** in the correct organization; 2. select an existing conversation or start one with an available contact; 3. keep the subject specific to the case or operational question; 4. use the related order for clinical files and structured order details; 5. resolve or archive the conversation when no follow-up remains. ![The clinic inbox](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-inbox.png) The inbox changes with the active workspace. Verify the organization and recipient before sending patient- or case-related information. ## Conversation scope [#conversation-scope] Use the ordinary inbox for organization-to-organization operational discussion. Use the order communication panel when the message belongs to one case; that keeps the conversation beside its files, status, patient, and production history. Messages do not replace structured actions. Change a due date in the order, record a hold through the hold control, attach a file through the file area, and record payment through finance. The message can explain the decision, but the structured record remains the source of truth. ## Notifications [#notifications] Inbox activity can use the user's configured email, SMS, WhatsApp, or push channels. Organization Twilio settings control the lab-owned SMS/WhatsApp provider; personal preferences control whether the user wants each channel. --- # Feature map A complete map of GuideLab clinic, laboratory, account, finance, and settings features. Documentation: https://docs.guidelab.co/guides/feature-map Use this page as the product index. The active organization determines whether you see the clinic or laboratory navigation. ![The organization switcher with both workspace types](https://assets.guidelab.co/docs/guides/2026-08-16/organization-switcher.png) ## Clinic workspace [#clinic-workspace] | Feature | What it is for | Guide | | ---------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | | Dashboard | Operational and finance summary for the active clinic | [Clinic overview](/guides/clinic/overview) | | Orders | Draft, submit, filter, and track laboratory cases | [Labs and orders](/guides/clinic/labs-and-orders) | | Calendar | Date-based view of clinic cases and deadlines | [Clinic calendar](/guides/clinic/calendar) | | Patients | Patient identity, contact data, notes, files, and order history | [Patients](/guides/clinic/patients) | | Inbox | Conversations with connected organizations | [Inbox](/guides/communications/inbox) | | Inventory | Clinic stock, suppliers, purchasing, and movements | [Clinic inventory](/guides/clinic/inventory) | | Finances | Laboratory invoices, credits, statements, balances, and payments | [Clinic finance](/guides/finance/clinic-finance) | | Settings | Company, team, payment methods, integrations, labs, locations, scanners, filters, and inventory rules | [Clinic settings](/guides/settings/clinic-settings) | | Uploaded Files | Clinic-wide scan, photo, document, X-ray, and other file library | [Files and scanners](/guides/clinic/files-and-scanners) | | Scanner Explorer | Browse cases exposed by connected scanner APIs | [Files and scanners](/guides/clinic/files-and-scanners) | ## Laboratory workspace [#laboratory-workspace] | Feature | What it is for | Guide | | ---------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | | Dashboard | Blocked-order triage and financial trend summary | [Lab overview](/guides/lab/overview) | | Orders | Drafts, approvals, active work, holds, completion, and shipment views | [Orders and statuses](/guides/lab/orders-and-production) | | Calendar | Scheduled laboratory workload | [Lab calendar](/guides/lab/calendar) | | Scan Inbox | Intake from supported scanner connections | [Scan Inbox](/guides/lab/scan-inbox) | | Clients | Clinic practices, contacts, shared patients, partnership details, and client-level finance | [Clients](/guides/lab/clients) | | Production | My tasks, room pool, statistics, history, trays, and workflow progression | [Production](/guides/lab/production) | | Inbox | Organization and order communication | [Inbox](/guides/communications/inbox) | | Inventory | Materials, suppliers, purchasing, stock valuation, and movements | [Inventory](/guides/inventory/overview) | | Finances | Accounts, invoices, credits, overpayments, expenses, reconciliation, consolidations, statements, transactions, and ageing | [Lab finance](/guides/finance/lab-finance) | | Reports | Built-in and custom operational reporting | [Reports](/guides/lab/reports) | | Settings | Complete lab configuration surface | [Settings reference](/guides/settings/reference) | ## Personal account [#personal-account] Profile, password, language, two-factor authentication, sessions, notification channels, and invitations belong to the user rather than one organization. See [Personal account settings](/guides/getting-started/personal-account). If a guide says a feature is owner-only or manager-only, the API enforces the same boundary. A disabled control is not the only protection. --- # Clinic finance Detailed reference for laboratory invoices, credit notes, statements, balances, payments, and autopay. Documentation: https://docs.guidelab.co/guides/finance/clinic-finance Clinic finance shows records issued by connected laboratories. It is organized around what the clinic owes, has paid, or can offset with credit. ![Clinic finance summary and invoice register](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-finance-invoices.png) ## Invoices [#invoices] Use search, sorting, pagination, and view controls to find an invoice. Review the lab, status, total, amount still due, issue date, due date, and line items before paying. Payment availability depends on the lab's Stripe connection, partnership payment policy, and the clinic's saved payment method. ## Credit notes [#credit-notes] Credit notes show the total issued and value remaining for allocation. A credit does not automatically mean cash was refunded; open the record to see how it was allocated. ## Statements [#statements] Statements summarize opening balance, invoices, credits, payments, closing balance, and total due for a lab and period. Patient names may appear depending on the laboratory's statement setting. ## Payment methods and autopay [#payment-methods-and-autopay] ![Clinic payment-method settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-clinic-billing.png) Payment methods are managed per laboratory under **Settings → Billing**. When saved-card autopay is enabled, GuideLab can attempt the saved card on the due date and again 3 and 7 days later while the invoice remains unpaid. Only enable it after confirming the card, billing authority, and connected lab. --- # Laboratory finance Detailed reference for accounts, invoices, credits, overpayments, expenses, reconciliation, consolidations, statements, transactions, and aged balances. Documentation: https://docs.guidelab.co/guides/finance/lab-finance The laboratory finance sidebar is a complete accounts-receivable and operational finance workspace. ## Overview and accounts [#overview-and-accounts] ![Laboratory finance accounts](https://assets.guidelab.co/docs/guides/2026-08-16/finance-accounts.png) * **Overview** summarizes outstanding value, monthly invoicing, payments, overdue totals, recent invoices, and recent payments by currency. * **Accounts** gives each practice's outstanding, total invoiced, payments, overdue value, available credit, and last payment. Open an account for its invoice and transaction history. ## Invoices and credit [#invoices-and-credit] ![Laboratory invoice register](https://assets.guidelab.co/docs/guides/2026-08-16/finance-invoices.png) * **Invoices** separates all, awaiting payment, paid, overdue, and draft records. Rows expose practice, doctor, status, total, due, issue date, and due date. * An order's shipping charge is billed as its own invoice line at its shipping type's VAT rate. A discount never applies to it, whether it is an upfront payment discount or one added to a draft invoice, and a draft's discount cannot exceed the subtotal of its other lines. * **Credit Notes** tracks issued, partly allocated, fully allocated, and voided credits, including remaining value. * **Overpayments** tracks original payment, linked invoice, overpaid, refunded, remaining, and date; allocate or refund through the permitted actions. ![Credit-note register](https://assets.guidelab.co/docs/guides/2026-08-16/finance-credit-notes.png) ## Expenses and reconciliation [#expenses-and-reconciliation] * **Expenses** records manual cash expenses in the reporting currency, with pending, paid, and void states plus original and reporting amounts. * **Stripe Reconciliation** exposes provider-side discrepancies and financial adjustments. It is limited to laboratory owners and administrators. ![Manager-gated Stripe reconciliation](https://assets.guidelab.co/docs/guides/2026-08-16/finance-reconciliation.png) ## Consolidations, statements, and ledger views [#consolidations-statements-and-ledger-views] * **Consolidations** groups eligible invoices for one recipient, currency, and period into a consolidated document. * **Statements** generates practice account summaries for a selected date or period. * **Transactions** is the chronological ledger-style list and can be filtered by type or exported. * **Aged Balances** splits open receivables into current, 1–30, 31–60, and 61+ day buckets. ![Aged balance buckets](https://assets.guidelab.co/docs/guides/2026-08-16/finance-aged-balances.png) ## Configuration [#configuration] **Settings → Finance settings** controls default invoice terms, list window, reminder milestones, overdue credit hold, terms, bank transfer information, nominal code, statement options, late fees, finance email automation, payment policy, and sales tax. See [Finance settings and data](/guides/settings/finance-and-data). The stage invoice register currently returns an internal-server error. Other finance sections load, but invoice-dependent actions should be treated as unverified until that defect is fixed. --- # Finance overview Understand how clinic and laboratory finance records relate to orders, payments, credits, and statements. Documentation: https://docs.guidelab.co/guides/finance/overview Finance begins with the order but has its own lifecycle. A completed laboratory order can create an invoice; payments, credits, overpayments, expenses, and statements then change the account position without changing the clinical case. ![The laboratory finance overview](https://assets.guidelab.co/docs/guides/2026-08-16/finance-overview.png) ## Record relationships [#record-relationships] 1. an order establishes the practice, products, prices, and currency; 2. completion creates or enables the invoice according to lab settings; 3. payment activity reduces the amount due; 4. a credit note reduces or offsets billed value; 5. an overpayment remains available for allocation or refund; 6. statements summarize account activity for a period; 7. aged balances group outstanding value by lateness. ## Responsibilities [#responsibilities] * The laboratory owns invoice and finance configuration. * The clinic reviews what connected labs bill and manages its permitted payment methods. * Owners control subscriptions, Stripe connections, and saved payment methods. * Lab owners/admins can access finance adjustments such as reconciliation. GuideLab operational finance does not replace statutory accounting. Reconcile exports and provider activity against the accounting source of truth. Continue with [Laboratory finance](/guides/finance/lab-finance) or [Clinic finance](/guides/finance/clinic-finance). --- # Finance and reports Choose the detailed finance or laboratory reporting guide for your workspace. Documentation: https://docs.guidelab.co/guides/finance-reports The **Finances** area gives each organization a different commercial workspace. This page remains as a short directory for existing links; use the detailed guides below for every register, filter, setting, and workflow. ## Laboratory finance [#laboratory-finance] Use the laboratory finance workspace to review the overview, accounts, invoices, credit notes, overpayments, expenses, Stripe reconciliation, consolidations, statements, transactions, and aged balances. ![The laboratory finances page](https://assets.guidelab.co/docs/guides/2026-08-16/lab-finances.png) [Open the laboratory finance guide](/guides/finance/lab-finance) ## Clinic finance [#clinic-finance] Use the clinic finance workspace to review invoices, credit notes, and statements associated with laboratory orders and payments. ![The clinic finances page](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-finances.png) [Open the clinic finance guide](/guides/finance/clinic-finance) ## Reports [#reports] Laboratory users can open **Reports** from the sidebar to explore 18 templates covering operations, sales and clients, finance, quality, logistics and stock. Owners and admins can create shared custom reports. The reporting guide explains metric definitions, comparisons, drill-down, CSV exports and browser printing. [Open the laboratory reports guide](/guides/lab/reports) Finance data should be reconciled against the accounting source of truth before it is used for tax, payout, or statutory reporting. --- # Create an organization Create and configure a new clinic or dental laboratory step by step. Documentation: https://docs.guidelab.co/guides/getting-started/create-organization Owners can create a clinic or laboratory from the organization switcher. Have the legal name, contact details, regional settings, and primary location ready. ### Choose the organization type [#choose-the-organization-type] From **Join or create organization**, select **Create new organization** and choose **Dental Practice** for a clinic or **Dental Lab** for a laboratory. ![Choose a dental practice or dental lab](https://assets.guidelab.co/docs/guides/2026-08-16/organization-create-start.png) ### Name the organization [#name-the-organization] Enter the organization name and a unique URL slug. The slug uses lowercase letters, numbers, and hyphens. ![The empty dental practice creation form](https://assets.guidelab.co/docs/guides/2026-08-16/organization-create-clinic.png) ![A completed organization name and slug](https://assets.guidelab.co/docs/guides/2026-08-16/organization-create-clinic-filled.png) ### Add business details [#add-business-details] Enter the support and billing contacts, phone number, website, company number, tax details, and business address. Fields marked with an asterisk are required. ![Business details during clinic onboarding](https://assets.guidelab.co/docs/guides/2026-08-16/onboarding-business.png) ### Set regional defaults [#set-regional-defaults] Choose the timezone and currency used for dates, deadlines, catalog prices, and financial reporting. ![Regional settings during onboarding](https://assets.guidelab.co/docs/guides/2026-08-16/onboarding-regional.png) ### Create the primary location [#create-the-primary-location] Name the first location and confirm its address. You can add more locations later in **Settings**. ![Primary location details during onboarding](https://assets.guidelab.co/docs/guides/2026-08-16/onboarding-location.png) After onboarding, the new organization appears in the switcher. Clinic owners should next add a patient and connect to a lab; lab owners should configure the catalog and production workflow. A clinic order requires a team member who can be selected as the reference doctor. Invite that person and assign the appropriate clinical role before starting the first order. --- # Personal account settings Manage profile, security, language, sessions, notifications, and invitations. Documentation: https://docs.guidelab.co/guides/getting-started/personal-account Personal account settings apply to the signed-in user across organizations. Open the user menu, then choose **Account settings**. ![Notification preferences for the current account](https://assets.guidelab.co/docs/guides/2026-08-16/settings-account-notifications.png) ## Profile and security [#profile-and-security] The **Profile** page contains: * avatar, full name, and phone number; * display language; * password change using the current password; * TOTP-based two-factor authentication; * active-session review and revocation; * account erasure in the danger zone. Email changes are handled through support. Account erasure revokes the active profile, while records required for clinical, financial, or audit retention may remain. ## Notification preferences [#notification-preferences] Choose channels independently for: * orders, including optional per-event rules; * partnership invitations and status changes; * chat messages; * finance events; * team membership and join requests; * low-stock inventory alerts. Available channels are email, SMS, WhatsApp, and browser push. Browser push must also be enabled on the current device. Saving one category does not implicitly save another category. ## My Invitations [#my-invitations] Invitations are tied to a verified mailbox. Verify the account email before expecting organization invitations to appear. Accepting an invitation adds the membership and lets you switch into that organization; declining removes the invitation. --- # Roles and access Choose a lab or clinic role and review its allowed and restricted actions before assigning it. Documentation: https://docs.guidelab.co/guides/getting-started/roles-and-access Your role applies to the active organization. You can have different roles in different labs and clinics. Within the areas your role permits, records are visible across that organization. ## Lab roles [#lab-roles] | Role | Can do | Cannot do | | ----------- | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | | Owner | Manage daily work, settings, team, finance and ownership | — | | Lab Manager | Manage orders, production, inventory, dispatch, settings, team and finance, including refunds | Change ownership, subscriptions, Stripe connections, banking details or API keys | | Technician | Manage orders, scans, files, messages, production tasks and assignments, quality checks, inventory and dispatch | Open finance or report screens; change settings or team roles | | Accounts | View operational records; manage invoices, credits, payments, refunds, expenses, reconciliation and financial exports | Change orders, production, inventory or dispatch; send operational messages; change settings or team roles | Owners and Lab Managers can view technician-time reports. Accounts can run other reports and export financial reports; general organization data exports remain restricted to owners and managers. Room assignments and working hours determine who can be scheduled, while job roles determine who can view or manage production. ## Clinic roles [#clinic-roles] | Role | Can do | Cannot do | | ---------------- | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | | Owner | Manage clinic work, clinical reviews, settings, team, finance and ownership | — | | Practice Manager | Manage patients, orders, files, messages, clinical reviews, settings, team and finance | Change ownership, subscriptions, saved payment methods or API keys | | Dentist | Manage patients, orders, files and messages; approve CAD designs and surgical reports or request changes | Open finance screens; change settings or team roles | | Reception | Manage patients, files and messages; submit every order type, including CAD, surgical and payment-required orders | Approve CAD designs or surgical reports, request clinical changes, open finance screens or manage the team | Reference-doctor selection is separate from the role of the person entering the order. Reception can submit an order for its selected eligible doctor without receiving that doctor's clinical approval permission. ## Prices, payments and settings [#prices-payments-and-settings] Operational roles can see case prices and payment status. Reception can complete a payment required to submit an order; this does not grant access to invoice settlement, saved payment-method management or the clinic's finance screens. Every recognized role can inspect non-financial settings. Changes are restricted to owners and managers. Finance settings are visible only to roles with finance access, and banking details and Stripe controls can be changed only by an owner. Invalid or organization-incompatible roles are denied access. ## Assign a role [#assign-a-role] 1. Open **Settings → Team** and choose **Invite member**, or open an existing member's role dialog. 2. Select a role card. The dialog lists what the role **can do** and **cannot do**. When editing a member, it also marks permissions being added or removed. 3. Review the access before saving. **Compare roles** opens a side-by-side table for the active organization. 4. Invitees accept from **Account Settings → My Invitations**. A join request also opens a role dialog before approval. Only an owner can grant another person ownership. Managers can assign the other roles for their organization. Existing owner and self-change protections still apply. Shareable join codes offer Technician or Lab Manager for labs, and Reception or Practice Manager for clinics; they never grant Owner, Accounts or Dentist. Existing Staff memberships, invitations and codes remain compatible: Staff is shown and enforced as Technician in a lab and Reception in a clinic. Newly assigned roles use the explicit job name. Selecting the equivalent job for an existing Staff member does not rewrite their membership. --- # Workspaces and navigation Switch between clinic and lab organizations and understand the GuideLab sidebar. Documentation: https://docs.guidelab.co/guides/getting-started/workspaces A GuideLab account can belong to more than one organization. The active organization controls the data you see and whether the sidebar shows clinic or laboratory tools. ![The organization switcher with Vivo and GuideLab Docs Clinic](https://assets.guidelab.co/docs/guides/2026-08-16/organization-switcher.png) ## Switch organizations [#switch-organizations] Click the organization name and logo at the top-left of the sidebar. Select the clinic or lab you want to work in. The organization type is shown under its name. Check the sidebar before making changes. A clinic shows **Patients**, while a lab shows **Clients**, **Production**, **Scan Inbox**, and **Reports**. ## Join or create another organization [#join-or-create-another-organization] Choose **Join or create organization** from the switcher. Select **Create new organization** to start a new clinic or lab, or use an invitation to join an existing team. ![The join or create organization page](https://assets.guidelab.co/docs/guides/2026-08-16/organization-join-create.png) Always confirm the organization name before creating an order, patient, supplier, or financial record. Data belongs to the active workspace. Next: [Create an organization](/guides/getting-started/create-organization). --- # GuideLab guides Step-by-step guides for clinics and dental laboratories using GuideLab. Documentation: https://docs.guidelab.co/guides GuideLab brings clinic ordering and laboratory operations into one workspace. These guides follow the product screen by screen, from creating an organization to managing patients, orders, production, inventory, finance, and settings. ![The GuideLab organization switcher showing a laboratory and a clinic](https://assets.guidelab.co/docs/guides/2026-08-16/organization-switcher.png) ## Choose your path [#choose-your-path] * **Complete index:** use the [Feature map](/guides/feature-map) to find every sidebar area and settings screen by name. * **New to GuideLab:** start with [Workspaces and navigation](/guides/getting-started/workspaces), then [Create an organization](/guides/getting-started/create-organization). * **Clinic team:** follow the [Clinic overview](/guides/clinic/overview), [Patients](/guides/clinic/patients), and [Labs and orders](/guides/clinic/labs-and-orders) guides. * **Laboratory team:** begin with the [Lab overview](/guides/lab/overview), then configure [Clients](/guides/lab/clients) and [Orders and production](/guides/lab/orders-and-production). * **Operations:** see [Inventory](/guides/inventory/overview), [Finance](/guides/finance/overview), [Inbox](/guides/communications/inbox), and the complete [Settings reference](/guides/settings/reference). The screenshots use a synthetic clinic named **GuideLab Docs Clinic**, a synthetic patient named **Alex Example**, and the existing stage laboratory **Vivo**. No customer or production records are used. ## Guide conventions [#guide-conventions] Page names and button labels are written exactly as they appear in the app. Where a feature differs between clinic and lab workspaces, the guide calls out the organization type explicitly. Each settings article explains what the controls affect downstream, who can change them, and what should be verified after a change. The reference page also lists every current clinic and laboratory settings route so less frequently used features are not omitted. For programmatic integrations, use the [API guide](/) and generated [API reference](/api-reference). --- # Inventory overview Monitor stock value, availability, attention items, and recent movements. Documentation: https://docs.guidelab.co/guides/inventory/overview Open **Inventory** to see the current stock position. The dashboard summarizes inventory value, category distribution, low or unavailable stock, expiring items, and recent movements. ![A populated inventory dashboard](https://assets.guidelab.co/docs/guides/2026-08-16/inventory-dashboard.png) ## Read the dashboard [#read-the-dashboard] * **Inventory pulse** shows total recorded stock value and item health. * **Inventory by category** explains where the value is held. * **Needs attention** highlights low, unavailable, or expiring stock. * **Recent activity** records additions and removals. Minimum and maximum quantities set on each item drive the dashboard's health signals. Keep those limits current when usage changes. Next: [Create suppliers and items](/guides/inventory/suppliers-and-items). --- # Purchase orders Create, review, and send a purchase order for inventory stock. Documentation: https://docs.guidelab.co/guides/inventory/purchase-orders Purchase orders group replenishment items under one supplier and track the order from draft through receipt. ### Start the order [#start-the-order] Open **Inventory → Purchase Orders** and click **New Purchase Order**. ![The purchase order register](https://assets.guidelab.co/docs/guides/2026-08-16/inventory-purchase-orders.png) ### Add supplier, delivery, and line items [#add-supplier-delivery-and-line-items] Choose the supplier, add the expected delivery date and notes, then select each inventory item and quantity. Review the calculated total before creating the order. ![The new purchase order form](https://assets.guidelab.co/docs/guides/2026-08-16/inventory-add-purchase-order.png) ### Review and send [#review-and-send] Open the newly created draft, confirm every line, and mark it sent when the supplier order has actually been placed. Update receipt status only when the stock arrives. Creating a purchase order does not replace the stock movement itself. Confirm the delivered quantities when goods are received. --- # Suppliers and items Add an inventory supplier and create a stocked item. Documentation: https://docs.guidelab.co/guides/inventory/suppliers-and-items Create the supplier before any item that references it. This keeps purchase orders, contact details, and stock reporting connected. ### Add a supplier [#add-a-supplier] Open **Inventory → Suppliers** and click **Add Supplier**. Enter the supplier name, code, permitted contact details, website, address, and notes. ![The supplier list](https://assets.guidelab.co/docs/guides/2026-08-16/inventory-suppliers.png) ![The add supplier form](https://assets.guidelab.co/docs/guides/2026-08-16/inventory-add-supplier.png) ### Add an item [#add-an-item] Open **Items**, click **Add Item**, and provide the name, SKU, category, supplier, quantity, stock limits, unit cost, and storage location. Add lot and expiry data when it applies. ![The inventory item list](https://assets.guidelab.co/docs/guides/2026-08-16/inventory-items.png) ![The add inventory item form](https://assets.guidelab.co/docs/guides/2026-08-16/inventory-add-item.png) ### Review stock health [#review-stock-health] Return to the dashboard and confirm that quantity, valuation, category, and attention status are correct. Use unique SKUs and supplier codes so the same material is not created twice. Next: [Purchase orders](/guides/inventory/purchase-orders). --- # Laboratory calendar Review scheduled laboratory work and understand the working-calendar rules behind due dates. Documentation: https://docs.guidelab.co/guides/lab/calendar The lab calendar shows scheduled cases. Use it alongside the production room views to compare due workload with available capacity. ![The laboratory calendar](https://assets.guidelab.co/docs/guides/2026-08-16/lab-calendar.png) ## Working calendar settings [#working-calendar-settings] ![Working days and closure dates](https://assets.guidelab.co/docs/guides/2026-08-16/settings-calendar-settings.png) Owners and admins configure: * operating weekdays; * recurring or one-time bank holidays and closures; * custom time-off periods; * active and inactive closure records. These rules feed turnaround and due-date calculations. Production planning also uses the daily cutoff, buffer days, and product or task duration. After changing the calendar, test a representative order date rather than assuming every existing case has been rescheduled. --- # Clients Accept clinic partnerships and review each client's patients and orders. Documentation: https://docs.guidelab.co/guides/lab/clients The **Clients** area represents clinics that work with the laboratory. A client relationship starts as a partnership request and becomes active when the other organization accepts it. ![The laboratory client list with an active clinic](https://assets.guidelab.co/docs/guides/2026-08-16/lab-clients.png) ### Review incoming requests [#review-incoming-requests] Open **Clients** and inspect the incoming partnership. Confirm the clinic name before accepting it. ![An incoming clinic partnership request](https://assets.guidelab.co/docs/guides/2026-08-16/lab-partnership-incoming.png) ### Accept the partnership [#accept-the-partnership] Accepting activates the clinic relationship. The client page then summarizes active orders, contacts, and patients made available to the lab. ![An active client partnership](https://assets.guidelab.co/docs/guides/2026-08-16/lab-partnership-active.png) ### Work from the client page [#work-from-the-client-page] Use the client page to review clinic-specific work and create a new order for that clinic when needed. Only access patient records that the clinic has explicitly shared with your laboratory. ## Client directory tabs [#client-directory-tabs] ![The practices directory](https://assets.guidelab.co/docs/guides/2026-08-16/lab-clients-practices.png) * **Practices** shows contact address, relationship status, total orders, active orders, and last-order date. * **Contacts** lists clinic members associated with client organizations. * **Patients** lists patients shared with the lab, their clinic, date of birth, contact data, and order count. ![Patients shared with the laboratory](https://assets.guidelab.co/docs/guides/2026-08-16/lab-clients-patients.png) ## Client detail [#client-detail] Open a practice to see its overview, contacts, patients, orders, invoices, and partnership configuration. Client filters and practice groups help manage a larger network. A practice group can also be used for consolidated management, reporting, and custom exports. The **Create new clinic** action is for a lab-created client record. A direct organization partnership remains the preferred relationship when the clinic already uses GuideLab. Next: [Orders and production](/guides/lab/orders-and-production). --- # Orders and statuses Create, approve, filter, progress, hold, complete, cancel, and ship laboratory orders. Documentation: https://docs.guidelab.co/guides/lab/orders-and-production The order register is the laboratory's source for case status, clinic, contents, and due date. Drafts remain editable until the required order information is complete. ![The laboratory order register with a clinic draft](https://assets.guidelab.co/docs/guides/2026-08-16/lab-orders.png) ## Work with orders [#work-with-orders] * Use the status tabs to focus on cases needing approval, on hold, or completed. * Use **Filter** for narrower case searches and **View** to change the table presentation. * Open an order number to see or continue the case. * Use the calendar to review scheduled work by date. ## Create an order from the laboratory [#create-an-order-from-the-laboratory] The lab-side wizard uses the same core sequence as a clinic order, but the lab first selects the practice and reference doctor. It then selects or creates the patient, adds products, collects files and notes, reviews the case, and saves or submits the order. A lab draft must be persisted before it can advance beyond the first step. ## Status lifecycle [#status-lifecycle] | Status | Meaning | Valid next actions | | ----------- | -------------------------------------- | ------------------------------------------------- | | Draft | Incomplete and not submitted | Submit or cancel | | Submitted | Received and awaiting lab approval | Accept into progress, put on hold, or cancel | | In Progress | Accepted and moving through production | Complete, put on hold, or cancel | | On Hold | Paused with a recorded reason | Resume to submitted/in-progress or cancel | | Completed | Finished | Reopen to in-progress when correction is required | | Cancelled | Terminal cancellation | No further status transition | **Needs Approval** is the submitted-order work queue. **On Hold** is the blocked queue. **Completed** contains finished cases. **Shipments** tracks packing, ready, in-transit, exception, delivered, returned, and cancelled shipment states separately from the order status. ## Order detail [#order-detail] The detail page combines: * header, status actions, due date, practice, doctor, and patient; * product items and their configured options; * production phase and task progress; * required and submitted files; * hold, remake, and quality-control records; * communications, status history, and task history; * document, sticker, shipment, and finance actions when applicable. ### Shipping and shipments [#shipping-and-shipments] Under the items, the order's shipping line shows: * the clinic's shipping type and price, and the orders it ships with; * for your laboratory only: the weight and zone it was priced at, and a warning when products have no weight or the order carries no shipping charge. **Edit shipping** changes the type, insurance or combined shipment while the order is unpaid and not invoiced. Only this order's charge is recalculated. Packing orders together physically never changes a price. **Ship** opens the order's shipment, or creates one for the order and those it ships with. The same button appears on each row of the shipping room. 1. **Create shipment**: the unshipped quantities and the clinic's address are filled in. 2. **Start packing**, then **Pack all**. 3. **Mark ready**. 4. For a carrier shipment, **Add tracking label** with the carrier and tracking number. 5. **Dispatch**, which needs a passing quality check on every order. 6. **Mark delivered**, with the recipient's name. ![The laboratory calendar](https://assets.guidelab.co/docs/guides/2026-08-16/lab-calendar.png) Next: [Work with the production workspace](/guides/lab/production). --- # Lab overview Understand the laboratory dashboard and daily navigation. Documentation: https://docs.guidelab.co/guides/lab/overview The laboratory workspace covers the full case lifecycle: intake, client relationships, production, communication, stock, finance, reporting, and configuration. ![The Vivo laboratory dashboard](https://assets.guidelab.co/docs/guides/2026-08-16/lab-dashboard.png) ## Daily navigation [#daily-navigation] * **New order** creates a case on behalf of a connected clinic. * **Orders** is the case register, with status and due-date filters. * **Calendar** shows scheduled work. * **Scan Inbox** receives supported scanner submissions. * **Clients** manages clinic partnerships and shared patients. * **Production** visualizes cases across the configured workflow. * **Inventory**, **Finances**, and **Reports** support operations and management. ## Dashboard cards [#dashboard-cards] The **Blocked orders** card prioritizes work that is overdue or has remained blocked for more than 24 hours. Severity filters separate critical and high attention items. Open the complete on-hold view from **View all**. The income-versus-expenses chart can be viewed across seven months, twelve months, or year to date. It is a management summary; the finance module remains the source for individual accounts, invoices, payments, and expenses. ## Daily operating rhythm [#daily-operating-rhythm] 1. clear critical blocked-order exceptions; 2. review orders needing approval; 3. assign and perform work from **Production → My tasks**; 4. monitor the room **Pool** and due calendar; 5. triage the Scan Inbox and ordinary Inbox; 6. finish with inventory and finance exceptions. Use the dashboard's blocked-order panel to prioritize cases that are overdue or have remained blocked for more than 24 hours. Next: [Connect and manage clients](/guides/lab/clients). --- # Production Use My tasks, Pool, Statistics, History, rooms, trays, phases, and task progression. Documentation: https://docs.guidelab.co/guides/lab/production Production turns an accepted order into actionable laboratory work. The room, phase, task, tray, date, and operator assignments determine where the case appears. ## My tasks [#my-tasks] **My tasks** is the current operator's assigned work. Select a room and date, then open a case to perform or complete the next task. ![The My tasks production view](https://assets.guidelab.co/docs/guides/2026-08-16/production-my-tasks.png) ## Pool [#pool] **Pool** shows the room's unassigned or shared queue. Acceptance rooms can show cases waiting to be accepted. Assign work according to the laboratory's normal capacity and responsibility rules. ![The production pool](https://assets.guidelab.co/docs/guides/2026-08-16/production-pool.png) ## Statistics and history [#statistics-and-history] **Statistics** summarizes total, completed-today, in-progress, and overdue task counts. **History** is the activity log and can be filtered by tasks, status, phase, tray, files, and hold-file events. ![Production statistics](https://assets.guidelab.co/docs/guides/2026-08-16/production-statistics.png) ![Production history](https://assets.guidelab.co/docs/guides/2026-08-16/production-history.png) ## Configuration relationship [#configuration-relationship] * **Rooms** control workstation layout and location. * **Phases** define the ordered treatment/production stages. * **Tasks** define concrete work inside the process. * **Work Trays** identify the physical case carrier; one active order per tray. * **Printers** and label templates support physical production outputs. * **Production settings** control planning, cutoff, buffer, capacity, grouping, sorting, visible columns, barcode scanning, and product/category exclusions. Move a case only after its current work is complete. Use an on-hold reason when the case cannot progress, and record QC or remake information in its dedicated controls rather than free-text alone. --- # Reports Explore laboratory operations, sales, finance, quality and stock, then create shared custom reports. Documentation: https://docs.guidelab.co/guides/lab/reports Open **Reports** in the laboratory sidebar. The library contains 18 templates, grouped by business area, alongside reports saved by your team. Search by name or description; pinned saved reports appear first. ## Available reports [#available-reports] | Area | Report | What it answers | | ------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------- | | Operations | Daily briefing | How many orders are open or held, submitted today, or first completed today? | | Operations | Intake and output | How do submissions and first completions compare by day? | | Operations | Work in progress and holds | Which current orders are submitted, active or held? | | Operations | Turnaround and completion punctuality | How long does first completion take, and was it within the requested date captured at completion? | | Operations | Production workload | Which unfinished tasks, planned minutes and overdue tasks belong to each room and assignee? | | Operations | Technician time and output | How much recorded or inferred time and completed work belongs to each operator? Owners and admins only. | | Sales and clients | Sales over time | What are issued net sales, tax, fees and gross totals after credit notes? | | Sales and clients | Sales by client and doctor | Which clients and doctors account for net issued sales? | | Sales and clients | Product sales and mix | Which products and pricing units account for quantities and allocated net sales? | | Sales and clients | Client activity | Which clients are new, returning or inactive in the selected period? | | Finance | Aged receivables | What is outstanding today, grouped into current, 1–30, 31–60 and 61+ days overdue? | | Finance | Collections and cash flow | What completed receipts, refunds and paid expenses moved cash? | | Finance | Expense analysis | What expenses occurred, by category, supplier or payment status? | | Quality | Quality control results | What proportion of first inspections passed for each fulfillment revision? | | Quality | Remakes | How many submitted orders are explicitly recorded as replacements? | | Logistics and stock | Dispatch and delivery | What was scheduled, delivered, cancelled or returned, and how long was transit? | | Logistics and stock | Stock and reorder needs | What stock is available, below minimum, or needs reordering? | | Logistics and stock | Material movements | What changed in the stock ledger, including reversals? | ## Run and explore a report [#run-and-explore-a-report] 1. Open a template or saved report. 2. Choose a period and, when available, a previous-period or previous-year comparison. Use custom dates for a specific interval. 3. Add filters and select **Run report** to apply them. 4. Read the summary and chart, then inspect the table. Changing table pages does not change the summary or chart scope. 5. Select **View records** on a summary row to inspect its underlying records. **Back to summary** keeps your original filters. Order and financial document references link to their detail pages where available. Historical reports use the laboratory timezone and cover up to 366 days per period. An ongoing period stops at today; previous-period comparison uses the same number of elapsed calendar days. Workload, work in progress, stock and receivables are current snapshots and do not accept historical dates. Client activity uses the selected period to classify clients and has no comparison. The generation time, timezone and data-availability notes appear with the results. Missing history stays **Unknown**. Completed records without an event date are reported separately because they cannot be assigned to a period. Reopening an order does not move its first completion date. Historical reports retain archived business records; current operational snapshots exclude them. ## Create a custom report [#create-a-custom-report] Laboratory owners and admins can select **Create report**, or **Customize** an existing report to make a copy. All saved reports are shared with the laboratory. Choose a template or dataset, then select detail rows or summary metrics and breakdowns. Set the columns, date basis, filters, sort order and optional chart. Give the report a name, description, default period and optional comparison. Select **Preview**, review the result, then **Save**. Currency and quantity units must remain visible when their measures are selected. Owners and admins can edit, pin or archive saved reports. The library supports up to 200 active saved reports. If someone changes a report while you are editing it, reload the latest version before saving. Existing reports from the earlier builder keep their original definitions and direct links. ## Understand the figures [#understand-the-figures] Sales come from issued invoices less non-voided credit notes, by document issue date. Net sales exclude tax. Product allocations reconcile to document net amounts; fees and unattributed amounts stay visible, and shipping charged to clinics, less any credits of it, is its own **Shipping** row. These figures do not calculate profit or historical cost of goods sold. Receivables use current outstanding invoice balances. Cash flow and expenses use their stored reporting-currency amounts. Different currencies are never combined into one total; quantities retain their unit. Stock valuation uses the current unit cost. Technician time distinguishes recorded timer/manual minutes from inferred minutes. Time belongs to the operator on the time entry and its start date; first task completion belongs to its completion date and assignee. Quality control uses the first inspection of each fulfillment revision, and uninspected orders do not count as passing. Order completion does not establish delivery. ## Record remakes [#record-remakes] Create and submit the replacement through the normal order workflow. On the replacement order, an owner or admin can open **Remake**, select an original order belonging to the same client, and choose an active remake reason. Use the root original when there are multiple replacements. Corrections and removal retain audit history. This records the relationship; configure pricing separately. The remake rate is recorded replacement orders divided by all submitted orders in the period, based on replacement submission date. Earlier remakes are not inferred from discounts, notes or quality-control failures. ## Export and print [#export-and-print] Select **CSV** for a spreadsheet download, or **Print / Save PDF** to use your browser's print dialog. Outputs use the report and filters you have run and fetch a fresh snapshot, including all matching rows up to the export limit. A later export can reflect changes made after the displayed report was generated. Exports support up to 2,000 rows and 5 MiB. Oversized reports fail explicitly; narrow the period or filters before exporting. CSV preserves exact decimal amounts and currency columns, with localized headings and status labels. Rates in CSV are numeric fractions, such as `0.75` for 75%. Query and request limits protect shared capacity. If a report exceeds the input limit, reduce its historical range or use a smaller dataset. If the request budget is exhausted, wait for it to reset; repeated identical exports share a 15-minute request limit. Reports run on demand, with no scheduled delivery. --- # Scan Inbox Review incoming scanner cases and connect supported scanner providers. Documentation: https://docs.guidelab.co/guides/lab/scan-inbox The **Scan Inbox** is the landing area for cases received from supported scanner integrations. New submissions appear here before they are matched to GuideLab patients and orders. ![The laboratory Scan Inbox](https://assets.guidelab.co/docs/guides/2026-08-16/lab-scan-inbox.png) ## When the inbox is empty [#when-the-inbox-is-empty] An empty inbox is expected until a scanner integration is configured and sends data. Use the setup action on the page or open **Settings → Integrations** to connect the supported provider. ## Triage an incoming scan [#triage-an-incoming-scan] 1. confirm the originating clinic and patient identity; 2. review the submitted files and metadata; 3. match the submission to an existing order or create the correct case; 4. resolve duplicates before production begins. ## Scanner connections [#scanner-connections] **Settings → Scanner** has two areas: **Connections** for Medit, iTero, 3Shape, and other supported provider accounts, and **Settings** for global scanner behavior. The Scan Inbox remains empty until at least one connection can deliver cases. The order file step can also import directly from a connected scanner. That workflow selects the provider, case, and individual files before attaching them to the order. Treat scanner files as clinical data. Match the clinic and patient carefully before attaching them to an order. --- # Account and settings access Distinguish personal account settings from organization settings and understand read-only behavior. Documentation: https://docs.guidelab.co/guides/settings/account-and-access GuideLab has two settings scopes: * **Account settings** follow the signed-in person across every organization. * **Organization settings** belong to the active clinic or laboratory. ![Personal notification settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-account-notifications.png) ## Personal account scope [#personal-account-scope] **Profile** manages name, avatar, phone, language, password, two-factor authentication, active sessions, and account erasure. **Notifications** chooses channel preferences. **My Invitations** lists organization invitations after the mailbox is verified. ## Organization scope [#organization-scope] The settings sidebar changes when the active organization changes. Company, team, billing, partnerships, operational defaults, catalog, workflow, and finance settings never automatically copy between organizations. ## Read-only behavior [#read-only-behavior] Staff roles can inspect settings needed to understand the workflow, but inputs, buttons, checkboxes, selects, and obvious mutation links are locked. Owners and admins can manage most settings. Billing and selected provider controls remain owner-only. The API repeats these checks, so bypassing a disabled control does not grant access. See [Roles and access](/guides/getting-started/roles-and-access) for the role checklist. --- # Calendar, scanners, and inventory settings Configure working dates, scanner connections, stock alerts, expiry, automatic deduction, categories, and adjustment reasons. Documentation: https://docs.guidelab.co/guides/settings/calendar-scanner-and-inventory ## Working calendar [#working-calendar] ![Laboratory working calendar](https://assets.guidelab.co/docs/guides/2026-08-16/settings-calendar-settings.png) Choose the weekdays the lab operates and add recurring or one-time holidays and closures. These dates affect product due-date and turnaround calculations. An inactive closure remains in history but no longer removes the date from working time. ## Scanner connections [#scanner-connections] ![Scanner connection settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-scanner-settings.png) The scanner page separates **Connections** from global **Settings**. Add the provider, complete its supported authorization flow, select any related account, then verify a bounded case lookup before relying on the Scan Inbox or Scanner Explorer. ## Inventory behavior [#inventory-behavior] ![Inventory alert and automation settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-inventory-settings.png) * **Low Stock Alerts** uses the item's minimum quantity. * **Expiration Alert Days** sets the warning window before expiry. * **Auto-deduct on Order Completion** consumes product material requirements when the case completes. Auto-deduction needs accurate product-to-material quantities. Test a synthetic completion and verify the resulting stock movement before enabling it broadly. ## Categories and adjustment reasons [#categories-and-adjustment-reasons] ![Laboratory inventory categories](https://assets.guidelab.co/docs/guides/2026-08-16/settings-inventory-categories.png) Categories organize the stock list and valuation dashboard. Reorder them to match how staff browse inventory. ![Stock adjustment reasons](https://assets.guidelab.co/docs/guides/2026-08-16/settings-inventory-adjustment-reasons.png) Adjustment reasons provide an auditable vocabulary for manual add/remove, damage, expiry, correction, stocktake, and return movements. Use the closest reason and add a concise note instead of creating overlapping duplicates. --- # Catalog options and clinical vocabularies Configure materials, file requirements, components, shade systems, implant systems, and quality standards. Documentation: https://docs.guidelab.co/guides/settings/catalog-options These reusable settings keep product configuration consistent. Configure the shared vocabulary first, then reference it from products. ## Materials and components [#materials-and-components] ![Material settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-materials.png) * **Materials** represent substances available across the catalog, with a clear name and optional code. They can also connect products to inventory deduction. * **Components** represent reusable technical parts or selections used by multiple products. ![Reusable component settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-components.png) ## File requirements [#file-requirements] ![Required file settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-file-requirements.png) File requirements tell the order wizard what the clinic must attach. Define a recognizable requirement name, accepted formats, requirement level, and product association. Test both upload and reuse-from-patient-files paths. ## Shade and implant systems [#shade-and-implant-systems] ![Shade system settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-shade-systems.png) Shade systems define the ordered shade values exposed during product configuration. A default system can be used when the product does not override it. ![Implant system settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-implant-systems.png) Implant systems define manufacturers, systems, and platforms used for implant cases. Use controlled names rather than free-text duplicates. ## Quality standards [#quality-standards] ![Quality-standard settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-standards.png) Quality standards define reusable production/QC criteria. Pair them with the QC checklist and product/workflow configuration so completion records the intended checks. Deactivate an obsolete vocabulary item when historical orders still reference it. Renaming or deleting shared values can make old and new orders harder to compare. --- # Catalog products and pricing Configure orderable laboratory products, prices, turnaround, visibility, requirements, and conditional options. Documentation: https://docs.guidelab.co/guides/settings/catalog The laboratory catalog defines what clinics and lab users can add to an order. Product configuration also drives file requirements, material consumption, clinical options, price, due-date calculation, and production behavior. ![Products and pricing settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-products.png) ## Product model [#product-model] Review these areas for every product: | Area | Effect | | ---------------------- | ------------------------------------------------------------------------------------------------------------------------- | | Identity | Name, SKU/code, description, category, and searchability | | Availability | Active state and whether the item is shown in the catalog | | Commercial | Base price, currency, client price-list behavior, and optional markup | | Shipping | Weight in grams, which prices shipping; see [Shipping prices](/guides/settings/pickup-and-communications#shipping-prices) | | Scheduling | Turnaround or working-day duration used for due-date suggestions | | Clinical configuration | Materials, shades, implant options, components, and custom fields | | Files | Required attachment types and accepted formats | | Production | Tasks, phases, room behavior, material requirements, and planning exclusions | | Conditional behavior | Visibility and triggered product/configuration rules based on earlier answers | ## Catalog checklist [#catalog-checklist] * use a clear clinical name and description; * group related items consistently; * set the current price and currency; * enter the weight of every physical product, so shipping is priced by what an order really weighs (a blank weight counts as 0 g and is flagged to the lab); * record required options and specifications; * disable services the laboratory cannot currently accept; * test the clinic order wizard after a material catalog change. ## Bundles and categories [#bundles-and-categories] ![Bundle settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-bundles.png) **Bundles** combine multiple products into one orderable selection with bundle pricing. Test component quantities and the resulting required fields/files. ![Product category settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-product-categories.png) **Categories** create the hierarchy used by the order browser and reporting. Ordering affects navigation. Hiding a category or product removes it from future catalog selection without rewriting existing orders. Catalog changes affect future order entry. Existing orders retain their own recorded case details and should be reviewed independently. Next: [Configure catalog options and clinical vocabularies](/guides/settings/catalog-options). --- # Clinic settings Configure clinic profile, team, locations, billing, labs, and integrations. Documentation: https://docs.guidelab.co/guides/settings/clinic-settings Clinic owners use **Settings** to maintain the organization profile and the prerequisites for patient and order workflows. ![The clinic settings page](https://assets.guidelab.co/docs/guides/2026-08-16/clinic-settings.png) ## Recommended setup order [#recommended-setup-order] 1. confirm organization and business details; 2. create every operating location; 3. invite the clinic team and assign the correct roles; 4. connect to the laboratories the clinic uses; 5. configure billing and integrations; 6. verify that an eligible reference doctor is available before creating the first order. ## Clinic settings sections [#clinic-settings-sections] ### Account [#account] * **Company** controls brand, support/billing contacts, legal/tax identity, address, timezone, and currency. * **Team** manages members, invitations, join requests, and roles. * **Billing** manages saved cards and autopay separately for each lab. * **Integrations** currently contains Dentally; scanner providers live under **Scanner**. ### Partners and clinic operations [#partners-and-clinic-operations] * **My labs** and **Find labs** manage partnerships and order routing. * **Locations** manages branches and the default clinic address. * **Scanner** manages provider connections. * **Filter presets** creates saved order-list views. * **Inventory** configures alerts, categories, and adjustment reasons. ### Files [#files] * **Uploaded Files** is the clinic-wide file library. * **Scanner Explorer** browses provider cases after a scanner is connected. Only owners should change organization-wide settings. Review the active workspace in the organization switcher before editing them. See the [Complete settings reference](/guides/settings/reference) for every route. --- # Fatture in Cloud Connect a laboratory to Fatture in Cloud, choose the company, configure numbering and tax, map clients, and submit e-invoices to SDI. Documentation: https://docs.guidelab.co/guides/settings/fatture-in-cloud Fatture in Cloud is the Italian invoicing platform GuideLab uses as the fiscal ledger for laboratories that bill in euro. GuideLab issues the commercial document; Fatture in Cloud assigns its fiscal number, keeps it in the company ledger, and transmits it to the Sistema di Interscambio (SDI). The connection is made once per laboratory from **Settings → Integrations**, in the **Finance & Procurement** section. ## Before you start [#before-you-start] You need: * a Fatture in Cloud account with access to the company GuideLab should write into; * an organization that bills in **EUR**. Fatture in Cloud only holds euro documents, so the connect button stays disabled for any other currency and the card explains that the currency must be changed in Company settings first; * the **manager** role in the laboratory organization. Connecting, choosing the company, changing settings, and submitting to SDI are all manager-only. One Fatture in Cloud company can be linked to one GuideLab organization only. ## Connect [#connect] ### Start the authorization [#start-the-authorization] Open the **Fatture in Cloud** card and, on the **Connection** tab, select **Connect to Fatture in Cloud**. GuideLab redirects to Fatture in Cloud, where you sign in and approve the requested permissions. GuideLab asks for the permissions it needs and nothing more: read and create clients, create invoices and credit notes and update their payment schedules, and read your numeration series, VAT types, payment accounts and payment methods. Your Fatture in Cloud password is never seen by GuideLab, and the resulting access tokens are encrypted at rest. ### Choose the company [#choose-the-company] If the authorized account holds more than one company, the card shows **Choose the company** with each company's name and VAT number. Select the one GuideLab should write documents into. An account holding a single company is bound automatically and this step does not appear. A company already linked to another GuideLab organization is refused. ### Configure the ledger [#configure-the-ledger] Open the **Settings** tab. GuideLab reads the live configuration of the connected company, so the choices below are your own Fatture in Cloud settings, not a separate copy: * **Numeration series**: the series the fiscal number is assigned inside, for example `/GL`. Leave it empty to use the company's default series. * **Default VAT type**: applied to exported document lines. A taxed invoice without a configured VAT type is held for review rather than exported with a guess. * **VAT type per rate**: every VAT rate your laboratory charges needs its Fatture in Cloud VAT type, including the rates of your shipping types, because shipping is exported as its own line at its own rate. A line whose rate has no VAT type is held for review. * **Payment account** and **Payment method**: used when recording paid amounts on exported documents. * **Auto-export invoices on send**: exports an invoice as soon as it is issued in GuideLab. * **Auto-sync payments**: updates the document's payment schedule when a payment is recorded in GuideLab. Select **Save Settings** to apply them. ### Verify with one document [#verify-with-one-document] Issue a single invoice and open the **Sync Log** tab. The operation should appear as **Success** with the fiscal number Fatture in Cloud assigned, and the same document should be visible in your company ledger with the next progressive number in the chosen series. GuideLab creates the document without a number and never sends a progressive, so the series cannot gap or collide. The GuideLab invoice reference travels in the document's visible subject. ## Client mappings [#client-mappings] The **Client Mappings** tab links your clinics to Fatture in Cloud clients by fiscal identity, using the VAT number or tax code, never by name similarity. Mappings are created automatically the first time a document for that clinic is exported. The table shows the clinic, the matched Fatture in Cloud client, the fiscal identity used, and how the match was made: **VAT number**, **Tax code**, **Manual**, or **Auto-created**. To correct a match, select the client name and search your Fatture in Cloud clients, then pick the right one. To discard a match and let it be made again on the next export, remove it with the delete action on the row. ## Sync log [#sync-log] The **Sync Log** tab lists the most recent operations with their date, document type (**Invoice** or **Credit note**), action (**Create**, **Payments**, **SDI send**, **SDI status**), status, assigned fiscal number, and SDI state. An operation is one of: * **Success**: the operation completed on the Fatture in Cloud side; * **Pending**: the operation is queued or in progress; * **Failed**: the operation did not complete and can be retried; * **Needs review**: the document cannot be exported safely as it stands, for example a taxed invoice with no configured VAT type, or an outcome GuideLab could not confirm. Fix the underlying cause, then retry. **Retry** re-runs a failed or needs-review operation. GuideLab reconciles against the ledger before acting, so a retry does not create a duplicate document. ## Corrections [#corrections] A numbered fiscal document is never deleted or overwritten through the API. To correct an exported invoice, issue a credit note in GuideLab; it is exported as a nota di credito against the original. If a payment exists in Fatture in Cloud that GuideLab does not know about, payment reconciliation stops and reports the conflict instead of overwriting your ledger. ## Send an e-invoice to SDI [#send-an-e-invoice-to-sdi] SDI submission is switched off by default. Turning on **Enable SDI submission** in the **Settings** tab does not send anything: it only reveals the **Send to SDI** action on individual invoices in the sync log. To submit, find the invoice's successful **Create** operation in the sync log and select **Send to SDI**. A confirmation dialog states that this transmits a legal fiscal document to the Sistema di Interscambio through Fatture in Cloud, and that it cannot be recalled once sent. The e-invoice is validated before transmission. The **SDI** column then tracks the outcome: **Not sent**, **In progress**, **Delivered**, **Accepted**, **Rejected**, **Error**, or **Needs review**. Use **Refresh status** on an in-progress submission to fetch the current state; GuideLab also refreshes submissions in flight on its own. There is no automatic path to SDI in GuideLab. Every submission is a deliberate action on one named invoice, confirmed by a manager, and irreversible once accepted by the exchange system. Test against a trial company before submitting real documents. ## Disconnect [#disconnect] **Disconnect** on the **Connection** tab stops exporting invoices and payments to Fatture in Cloud. Documents already in your ledger are not affected, and you can reconnect at any time. Disconnecting does not revoke the authorization inside Fatture in Cloud itself. To remove GuideLab's access there as well, revoke it from your Fatture in Cloud account settings. ## If the connection fails [#if-the-connection-fails] The card reports the specific reason rather than a generic failure. The most common ones: * **the request expired**: the connection attempt is valid for a short window. Start it again from the integrations page; * **the company is already linked**: that Fatture in Cloud company belongs to another GuideLab organization; * **the tax details do not match**: the company's VAT number does not match the registration number on your GuideLab organization profile; * **no companies are visible**: the account you signed in with cannot reach the company. Sign in with one that can; * **euro billing required**: set the organization currency to EUR in Company settings, then connect. --- # Finance settings and data management Configure invoice, payment, tax, statement, and finance-email policy, then safely import, export, and restore archived records. Documentation: https://docs.guidelab.co/guides/settings/finance-and-data ## Finance settings [#finance-settings] ![Laboratory finance settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-finance-settings.png) Finance settings are split into **Main**, **Payments**, and **Sales Tax**. ### Main [#main] * invoice creation and default due policy or Net term; * invoice-list time window; * issue, pre-due, due-date, and overdue reminder milestones; * overdue credit hold that can override normal clinic payment policy; * invoice terms, bank-transfer information, and nominal code; * monthly statement day and display options; * late-fee policy; * automatic sales-invoice, sales-credit, statement, and consolidated-invoice emails. ### Payments and tax [#payments-and-tax] Payment settings define default partnership payment behavior and owner-only Stripe connection controls. Sales Tax manages the tax rates used by invoice lines. Confirm currency and accounting mappings before activation. ## Import [#import] ![GuideLab bundle and CSV import choices](https://assets.guidelab.co/docs/guides/2026-08-16/settings-import.png) Import either: * a GuideLab `.zip` bundle containing selected lab configuration; or * one CSV dataset for products, clients, price lists, or opening balances using guided column mapping. Review the preview, mapping, row limit, and validation errors before applying an import. Keep the source export and error report until reconciliation is complete. ## Export [#export] ![Selectable GuideLab export bundle](https://assets.guidelab.co/docs/guides/2026-08-16/settings-export.png) Bundle export can include products, production configuration, templates, lab settings, clients, finance settings, and a non-re-importable team roster. CSV exports provide focused tabular datasets. Live orders are not part of the production-configuration bundle section. Exports can contain personal, clinical, and financial data. Select the minimum sections, store the file securely, and delete temporary copies after use. ## Archive [#archive] ![Archived order register](https://assets.guidelab.co/docs/guides/2026-08-16/settings-archived-orders.png) Archived Orders and Archived Patients are searchable restore surfaces, not a hard-delete function. Restoring returns the record to the active workflow while preserving its history and relationships. ![Archived patient register](https://assets.guidelab.co/docs/guides/2026-08-16/settings-archived-patients.png) --- # Integrations Configure clinic, laboratory, scanner, finance, manufacturing, communication, and marketplace integrations. Documentation: https://docs.guidelab.co/guides/settings/integrations Integration settings show connection status and provider-specific configuration. Use sandbox or test provider accounts in stage. ![Laboratory integration directory](https://assets.guidelab.co/docs/guides/2026-08-16/settings-lab-integrations.png) ## Laboratory providers [#laboratory-providers] | Area | Providers | Purpose | | ------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | | Design and manufacturing | ExoCAD, HeyGears | CAD/CAM reconstruction/material mapping and cloud manufacturing | | Finance and procurement | Xero, [Fatture in Cloud](/guides/settings/fatture-in-cloud), Ariba | Accounting, Italian SDI e-invoicing, and cXML procurement | | Communication | Twilio | Laboratory-owned SMS and WhatsApp messaging | | Marketplace | Bite-Finder | Occlusion correction and bite analysis; send an order’s two jaw scans and receive the corrected result | | Coming soon | Microsoft 365 | Calendar and email integration | Provider configuration can include OAuth authorization, account/company selection, product or material mappings, tax/payment mappings, automation switches, sync logs, test actions, and credentials. A provider that fails to load should show an error state rather than being assumed disconnected. ## Clinic providers [#clinic-providers] ![Clinic integration directory](https://assets.guidelab.co/docs/guides/2026-08-16/settings-clinic-integrations.png) The clinic integration directory contains **Dentally** for patient-data sync. Scanner providers such as 3Shape, Medit, and iTero are managed under the dedicated **Scanner** page. ## Connection checklist [#connection-checklist] 1. confirm the active organization and provider environment; 2. authorize with the narrowest provider permissions; 3. select the exact provider account or company; 4. configure mappings and automation explicitly; 5. run the available test or limited sync; 6. inspect the sync log and one resulting GuideLab record; 7. document how to disconnect or rotate credentials. Never paste provider secrets into documentation, screenshots, issue logs, or ordinary notes. Use the application's credential controls and repository secret workflow. --- # Laboratory settings Configure the laboratory organization and its operational modules. Documentation: https://docs.guidelab.co/guides/settings/lab-settings Laboratory settings bring together business identity, locations, staff, client configuration, integrations, catalog, and production workflow. ![The laboratory settings page](https://assets.guidelab.co/docs/guides/2026-08-16/lab-settings.png) ## Recommended setup order [#recommended-setup-order] 1. confirm organization, regional, and location details; 2. invite the lab team and assign operational access; 3. configure services in the [Catalog](/guides/settings/catalog); 4. define rooms, phases, and tasks in [Workflow](/guides/settings/workflow); 5. connect supported scanner, finance, and communication integrations; 6. review client defaults before accepting the first clinic partnership. ## Settings sections [#settings-sections] The lab navigation is intentionally broad: * **Account:** company, team, subscription, and integrations; * **Partners:** clinic relationships and practice groups; * **Catalog:** products, bundles, categories, materials, required files, components, shade systems, implant systems, and standards; * **Workflow:** tasks, rooms, phases, printers, automations, and planning; * **Order operations:** intake, tags, filters, trays, holds/remakes, QC, calendar, scanners, inventory, pickup, and delivery; * **Communications:** email, stickers, WhatsApp, and document branding; * **Finance:** invoice, payment, tax, statement, and notification policy; * **Data:** bundle/CSV import, export, and archived records. Changes to catalog and workflow configuration affect downstream order entry and production, so make them deliberately and communicate them to the team. Use the [Complete settings reference](/guides/settings/reference) to find every route, then follow the detailed topic pages in this section. --- # Order operations settings Configure tags, filter presets, work trays, hold reasons, remakes, and QC. Documentation: https://docs.guidelab.co/guides/settings/order-operations Order-operation settings define how teams classify and find cases, and how exceptions are recorded. ## Tags and filter presets [#tags-and-filter-presets] ![Tag settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-tags.png) Tags are color-coded labels for custom order categories such as priority or an internal workflow distinction. They have a name, description, color, order, and active state. ![Saved order-filter presets](https://assets.guidelab.co/docs/guides/2026-08-16/settings-filter-presets.png) Filter presets create the cards shown above the order list. Each preset defines status and other filters, sort order, and visible columns. Built-in examples are All Orders, Needs Approval, On Hold, and Completed. ## Work trays [#work-trays] ![Physical work-tray settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-work-trays.png) Each physical tray has a unique code, optional color/description, and active state. A tray can be assigned to only one active order at a time. **Bulk Add** creates a bounded code sequence for new physical trays. ## Holds, remakes, and quality control [#holds-remakes-and-quality-control] ![Hold-reason settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-hold-reasons.png) Hold reasons are ordered choices used when pausing an order. Use specific, actionable reasons rather than ambiguous labels. ![Remake reason and QC configuration](https://assets.guidelab.co/docs/guides/2026-08-16/settings-remake-qc.png) **Remake** reasons can include a discount percentage. **QC List** items form the quality-control checklist. Keep financial treatment and quality evidence separate: a remake reason is not a substitute for recording failed QC criteria. --- # Organization, team, and billing Configure organization identity, team roles, laboratory subscriptions, and clinic payment methods. Documentation: https://docs.guidelab.co/guides/settings/organization-team-and-billing ## Company [#company] Company settings own the organization identity used across the application and generated documents: * organization and display name, slug, brand, and logo; * support, billing, phone, and website details; * business address and location defaults; * company, tax, or VAT identifiers; * timezone and currency. Timezone affects displayed dates and working-calendar calculations. Currency affects catalog pricing, inventory valuation, and finance records. Change either only after reviewing downstream consequences. ## Team [#team] Team settings list active members, pending invitations, and join requests. Owners/admins can invite, change permitted roles, or remove access. Confirm clinical roles separately when a person must appear as a reference doctor. ## Laboratory subscription [#laboratory-subscription] ![Laboratory plan and usage](https://assets.guidelab.co/docs/guides/2026-08-16/settings-lab-billing.png) The laboratory billing page shows: * trial or subscription state and current period; * accepted-case usage and allowance; * pooled storage usage and included limit; * additional storage units and price; * monthly or annual plan choices; * payment-detail and billing-portal actions. All plan and payment controls are owner-only. Accepted-case and storage figures should be reviewed before changing plan or add-on quantity. ## Clinic payment methods [#clinic-payment-methods] ![Clinic payment methods for a connected lab](https://assets.guidelab.co/docs/guides/2026-08-16/settings-clinic-billing.png) Clinic billing is grouped by connected laboratory. Each lab can have its own saved methods and autopay preference. Removing a card or changing autopay does not alter an already recorded payment. --- # Partnerships and practice groups Manage clinic-lab relationships, invitations, patient access, routing, and practice groups. Documentation: https://docs.guidelab.co/guides/settings/partnerships Partnerships authorize cross-organization workflows. They do not merge the two organizations or make every patient visible automatically. ## Clinic workflow [#clinic-workflow] Use **Find labs** to browse discoverable laboratories by service and send a request. **My labs** shows pending and active relationships and is the entry point for lab-specific routing and payment-method configuration. ![Finding a laboratory from clinic settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-clinic-find-labs.png) ## Laboratory workflow [#laboratory-workflow] Laboratories manage clinic relationships from **Clients**, not from settings. The Practices tab lists every partnership with a status filter, so pending clinic requests and sent invitations sit beside active clients. Accept or decline a request, resend or cancel an invitation, and suspend, reactivate or terminate a partnership from the row menu or the client detail page. **Invite Clinic** creates a new clinic and emails its owner; a clinic that already uses GuideLab sends the request from its own **Find labs** page. The client detail page has a **Partnership** tab for the price list and payment-policy override. After acceptance, the client directory should show the practice. Patient access is still granted by the clinic, and each order records its own clinic, doctor, patient, and commercial context. ## Practice groups [#practice-groups] ![Practice group settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-practice-groups.png) Practice groups organize partner clinics for reporting, consolidated management, and optional custom exports. Groups have a name, description, clinic membership, custom-export behavior, and active state. The stage settings pages currently report zero connected partners even though the client directory shows the active GuideLab Docs Clinic relationship. The defect is recorded internally; verify both surfaces until it is resolved. --- # Pickup, delivery, and communications settings Configure location routes, pickup requests, email, stickers, WhatsApp, and document branding. Documentation: https://docs.guidelab.co/guides/settings/pickup-and-communications ## Location routes and pickup requests [#location-routes-and-pickup-requests] ![Pickup and delivery route settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-location-route.png) A location route has a name, description, delivery-day count, default flag, and active state. The default route supplies the ordinary pickup/delivery behavior when no more specific route applies. ![Pickup request configuration](https://assets.guidelab.co/docs/guides/2026-08-16/settings-pickup-requests.png) Pickup-request settings define the form and workflow clinics use to ask for a case collection. Align the requested fields with the route and dispatch process. ## Shipping prices [#shipping-prices] **Settings › Shipping** sets what clinics pay for shipping. Nothing is charged until you create a shipping type. * **Types** are the choices a clinic sees at checkout, for example Standard courier, Express, Own driver or Collect at lab. Each has: * a method; * the VAT rate of the shipping line (blank uses your default rate); * optional insurance: a fixed amount or a percentage of the order's items. Deactivate a type to stop offering it. A type an order already uses cannot be deleted. * **Zones** group countries, and a country belongs to one zone. The optional **Rest of world** zone covers every other country. A destination no zone covers is not charged, and only your laboratory is warned. * **Rates** give each type and zone up to 10 prices of the form "from X g". The heaviest band an order reaches applies, and lighter orders pay the first band. An order weighs the sum of its physical products' weights. Products without a weight count as 0 g and are listed on this page. The price is fixed when the order is submitted or paid. It is never re-priced from the parcel you pack, and no discount applies to it. A clinic may combine a new order with an open order of its own that is due no earlier. It then pays only what the combined weight adds to the rate. A client's price list can give that clinic its own shipping price per type, in the price list editor's **Shipping** card: * a fixed price, or a discount (100% makes shipping free); * it never offers a type your rates do not cover; * a price list's general discount never applies to shipping. ## Email templates [#email-templates] ![Email template directory](https://assets.guidelab.co/docs/guides/2026-08-16/settings-email-templates.png) Email templates contain a name, subject, category, body, and permitted merge data. Preview with a synthetic context before attaching the template to an automation. Keep clinical details in structured records when possible. ## Sticker templates [#sticker-templates] ![Sticker template settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-sticker-templates.png) Sticker templates define printable product-label layouts. Categories organize templates; the designer controls size, static text, dynamic variables, barcode, and other elements. Print a physical test on the target printer. ## WhatsApp templates [#whatsapp-templates] ![WhatsApp event and template settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-whatsapp-templates.png) Custom WhatsApp templates are registered with Twilio and move through draft, pending, approved, or rejected states. An approved template can replace the GuideLab English default for a specific automatic event. **Sync All** refreshes provider approval state; it does not approve content itself. ## Document branding [#document-branding] ![Document branding settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-document-branding.png) Configure the document title, footer, logo, terms, patient/manufacture statement copy, and display options. Review a generated invoice, statement, or other document after any branding change. --- # Complete settings reference Every clinic, laboratory, and personal settings feature, with its purpose and downstream effect. Documentation: https://docs.guidelab.co/guides/settings/reference This is the complete settings index for the current GuideLab application. ![The full laboratory settings navigation](https://assets.guidelab.co/docs/guides/2026-08-16/lab-settings.png) ## Access rules [#access-rules] * Owners and admins manage most organization settings. * Staff can inspect most settings in a read-only state. * Organization billing and subscription controls are owner-only. * Laboratory finance settings are manager-accessible, but Stripe connection controls remain owner-only. * Personal account settings belong to the signed-in user, not the active organization. ## Clinic settings [#clinic-settings] | Setting | Purpose and downstream effect | | -------------------- | ------------------------------------------------------------------------------------- | | Settings | Directory of clinic configuration areas | | Company | Organization name, brand, contacts, company/tax data, address, timezone, and currency | | Team | Members, pending invitations, join requests, and organization roles | | Billing | Saved payment methods and permitted autopay behavior for each connected lab | | Integrations | Dentally patient-data synchronization; scanner providers are configured separately | | My labs | Active and pending laboratory relationships and routing | | Find labs | Search discoverable labs by service and request a partnership | | Locations | Clinic branches, addresses, phones, default location, and active state | | Scanner | Supported intraoral scanner connections and global scanner behavior | | Filter presets | Saved order-list filters, sort, columns, and live count cards | | Inventory settings | Low-stock alerts, expiry warning window, and auto-deduction | | Inventory categories | Ordered clinical stock categories | | Adjustment Reasons | Auditable reasons for manual stock changes | | Uploaded Files | Clinic-wide scans, photos, documents, X-rays, and other uploads | | Scanner Explorer | Cases available from connected scanner APIs | ## Laboratory settings: account and partners [#laboratory-settings-account-and-partners] | Setting | Purpose and downstream effect | | -------------------------- | ------------------------------------------------------------------------------------------- | | Company | Laboratory identity, brand, contacts, company/tax data, address, timezone, and currency | | Team | Members, invitations, join requests, and roles | | Billing & subscription | Plan, accepted-case allowance, pooled storage, add-ons, billing period, and payment details | | Integrations | ExoCAD, HeyGears, Xero, Fatture in Cloud, Ariba, Twilio, Bite-Finder, and future providers | | Clients (outside settings) | Clinic partnerships, invitations and per-client price list and payment terms | | Practice groups | Group clinics for management, reporting, consolidation, and custom export | ## Laboratory settings: catalog [#laboratory-settings-catalog] | Setting | Purpose and downstream effect | | ------------------ | --------------------------------------------------------------------------------------------------------------------------- | | Products & pricing | Orderable services, SKU, visibility, price, turnaround, material requirements, custom fields, and conditional configuration | | Bundles | One priced selection containing multiple catalog products | | Categories | Ordered product hierarchy used for browsing and reporting | | Materials | Reusable catalog materials and codes | | File requirements | Required order attachments and accepted formats | | Components | Reusable technical components referenced by products | | Shade systems | Shade options and default systems exposed in product configuration | | Implant systems | Implant manufacturers, systems, and platforms used by orders | | Quality standards | QC criteria that can be applied during production | ## Laboratory settings: workflow and order operations [#laboratory-settings-workflow-and-order-operations] | Setting | Purpose and downstream effect | | -------------------- | ------------------------------------------------------------------------------------------------ | | Tasks | Concrete production work and task behavior | | Rooms | Workstations, room layout, and production routing | | Phases | Ordered production stages, tasks, and planned-date offsets | | Printers | Physical output devices used by production and labels | | Automations | Trigger/condition/action rules for routing and notifications | | Production settings | Planning, cutoff, buffer, capacity, grouping, sorting, columns, barcode scanning, and exclusions | | Tags | Custom labels for order categorization | | Filter presets | Saved order-list views with live counts | | Work Trays | Physical tray codes, colors, active state, and current-order assignment | | Hold reasons | Ordered reasons used when pausing an order | | Remake & QC List | Remake reasons and discount percentages plus QC checklist items | | Calendar | Operating days, bank holidays, closures, and time off used by due-date calculations | | Scanner | Scanner-provider connections and global settings | | Inventory settings | Alerts, expiry window, and completion-time material deduction | | Inventory categories | Ordered material stock categories | | Adjustment Reasons | Auditable stock-change reasons | | Location route | Pickup/delivery routes, delivery days, default, and active state | | Pickup Requests | Clinic-facing pickup request form and workflow | | Shipping | Shipping types, zones, "from X g" prices, VAT and insurance clinics pay at checkout | ## Laboratory settings: communications, finance, and data [#laboratory-settings-communications-finance-and-data] | Setting | Purpose and downstream effect | | ------------------ | -------------------------------------------------------------------------------------------------------------------- | | Email Templates | Reusable and automated email subjects/bodies with merge data | | Sticker Templates | Printable product-label layouts and categories | | WhatsApp Templates | Twilio-approved templates and event-level selection | | Document branding | Titles, footer, logo, terms, manufacture statement, and product-detail options | | Finance settings | Invoice terms, reminders, credit hold, bank transfer, statements, late fees, payment policy, tax, and finance emails | | Import | Restore a GuideLab bundle or import products, clients, price lists, and balances from CSV | | Export | Re-importable bundle sections or focused CSV exports | | Archived Orders | Search and restore archived orders | | Archived Patients | Search and restore archived patient records | Use the following pages for detailed configuration guidance: * [Organization, team, and billing](/guides/settings/organization-team-and-billing) * [Integrations](/guides/settings/integrations) * [Partnerships and practice groups](/guides/settings/partnerships) * [Catalog products and pricing](/guides/settings/catalog) * [Catalog options and clinical vocabularies](/guides/settings/catalog-options) * [Workflow](/guides/settings/workflow) * [Order operations](/guides/settings/order-operations) * [Calendar, scanners, and inventory](/guides/settings/calendar-scanner-and-inventory) * [Pickup and communications](/guides/settings/pickup-and-communications) * [Finance and data](/guides/settings/finance-and-data) --- # Production workflow Configure tasks, rooms, phases, printers, automations, and production planning. Documentation: https://docs.guidelab.co/guides/settings/workflow Workflow settings define how submitted cases move through the laboratory. Rooms describe where work happens, phases describe the production sequence, and tasks describe the work performed. ![Production task settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-tasks.png) ### Create rooms [#create-rooms] Add the physical or logical work areas used by the lab. Each room can use a layout suited to ordinary production, acceptance/check-in, production planning, or shipping. ![Room settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-rooms.png) ### Define phases [#define-phases] Arrange the major production stages in the order cases normally pass through them. Phases can contain an ordered task list and a default planned-date offset. ![Phase settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-phases.png) ### Add tasks [#add-tasks] Create the concrete work items performed within the phases and assign their expected room or responsibility where supported. ### Validate with a test case [#validate-with-a-test-case] Create a non-production case and confirm it appears in the correct starting position, can advance through the intended path, and exposes the expected exceptions. ## Printers [#printers] Printers represent physical output devices used for production documents and labels. Confirm the device, paper/label format, and template before making it part of the production process. ![Printer settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-printers.png) ## Automations [#automations] Automations combine a trigger, conditions, and actions. They can route work, change operational state, or send notifications. Keep rules narrow, avoid overlapping triggers, and test with one synthetic order before activation. ![Automation settings](https://assets.guidelab.co/docs/guides/2026-08-16/settings-automations.png) ## Production planning settings [#production-planning-settings] ![Production planning configuration](https://assets.guidelab.co/docs/guides/2026-08-16/settings-production-settings.png) Configure: * whether planning is enabled; * daily cutoff and buffer working days; * completion-date organization; * default unit capacity; * task grouping and sorting; * prices, barcode scanning, and visible task columns; * product and category exclusions. Exclusions keep selected work outside automatic planning without removing it from the catalog. Avoid changing active workflow definitions in the middle of a busy production cycle without first checking the effect on in-progress cases. --- # GuideLab API REST API for GuideLab — clinics, labs, workflows, finance, files, and integrations. Documentation: https://docs.guidelab.co/ The **GuideLab API** is a REST API for the GuideLab dental lab management platform. It powers everything the web and desktop apps do: managing orders and patients, running production workflows, handling invoicing and payments, uploading clinical files, and integrating with scanners and third‑party tools. All requests are made to **`https://api.guidelab.co`**. The full machine‑readable specification is available at [`/api/openapi`](/api/openapi). ## Conventions [#conventions] * **Protocol** — HTTPS only. Requests and responses are JSON unless an endpoint explicitly deals with file uploads or downloads. * **Authentication** — every non‑public endpoint requires an authenticated session cookie or native device credential. See [Authentication](/authentication). * **Multi‑tenant** — GuideLab is multi‑tenant. Your session is scoped to an organization (a **lab** or a **clinic**), and endpoints operate on the data for that organization. Some routes are restricted to a specific organization type or role. * **Pagination** — list endpoints share a common page/limit contract. See [Pagination](/pagination). * **Errors** — failures use a consistent JSON envelope and standard HTTP status codes. See [Errors](/errors). ## API reference [#api-reference] The [API reference](/api-reference) is generated directly from the API's OpenAPI 3.1 specification. Endpoints are grouped by area — Orders, Patients, Partnerships, Invoices, Production, Files, and many more — with the full request and response schema for each operation. ## Using the docs with AI [#using-the-docs-with-ai] Every page can be exported as Markdown for use with an LLM: * **Copy for AI** / **Open** buttons at the top of each page. * [`/llms-full.txt`](/llms-full.txt) — the entire documentation as a single plain‑text file. * Append `.mdx` to any page URL to get its Markdown source. --- # Pagination How list endpoints page, limit, and search results. Documentation: https://docs.guidelab.co/pagination List endpoints share a common pagination contract. You request a page with query parameters, and the response includes the items plus pagination metadata. ## Query parameters [#query-parameters] | Parameter | Type | Default | Description | | --------- | ------- | ------- | -------------------------------- | | `page` | integer | `1` | Page number (1‑based). | | `limit` | integer | `20` | Items per page. | | `search` | string | — | Optional free‑text search query. | ```bash curl "https://api.guidelab.co/patients?page=2&limit=50&search=smith" \ -H "Authorization: Bearer gl_device_v1_" ``` ## Response metadata [#response-metadata] Paginated responses include a `pagination` object alongside the data: ```json { "data": [ /* … items … */ ], "pagination": { "page": 2, "limit": 50, "total": 327, "totalPages": 7 } } ``` | Field | Type | Description | | ------------ | ------- | ----------------------------------------- | | `page` | integer | The current page number. | | `limit` | integer | Items per page used for this response. | | `total` | integer | Total number of items matching the query. | | `totalPages` | integer | Total number of pages. | The exact shape of the data array and any additional filters are documented per endpoint in the [API reference](/api-reference). `page`, `limit`, and `search` are consistent across all paginated list endpoints. --- # Webhooks Inbound webhooks GuideLab receives from third‑party services. Documentation: https://docs.guidelab.co/webhooks GuideLab exposes a small number of **inbound** webhook endpoints under `/webhooks`. These are called by external services — they are not events that GuideLab sends to your servers. Each is verified against the provider's signature and is therefore public (no GuideLab session required). ## Endpoints [#endpoints] | Method | Path | Source | | ------ | -------------------------- | ----------------------------------------- | | `POST` | `/webhooks/stripe-connect` | Stripe Connect — payment & account events | | `POST` | `/webhooks/medit` | Medit — scanner / case events | See the [Webhooks section of the API reference](/api-reference/webhooks) for the full payloads and responses. ## Stripe Connect [#stripe-connect] `POST /webhooks/stripe-connect` receives [Stripe Connect](https://stripe.com/connect) events (payments, payouts, and connected‑account updates) and reconciles them with GuideLab's finance records. Stripe signs each request; GuideLab verifies the signature before processing. ## Medit [#medit] `POST /webhooks/medit` receives events from the [Medit](https://www.medit.com) scanner integration, used to ingest scan data into the relevant case. These endpoints are configured in the respective provider dashboards to point at `https://api.guidelab.co/webhooks/…`. You don't call them directly — they're documented here so the behaviour of the integration is transparent. --- # List files `GET https://api.guidelab.co/files` Returns a paginated list of files for the current organization. Labs see all files; clinics see only their own. Supports filtering by patient, clinic, file type, and unassigned status. Documentation: https://docs.guidelab.co/api-reference/files/listFiles ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `orderId` (string) (in: query): Filter by an accessible order ID - `page` (integer) (in: query): Page number Default: `1` - `limit` (integer) (in: query): Items per page Default: `20` - `patientId` (string) (in: query): Filter by patient ID - `clinicId` (string) (in: query): Filter by clinic ID (lab only) - `type` (string) (in: query): Filter by file type: scan, photo, prescription, xray, other - `unassigned` () (in: query): Show only files not attached to an order Default: `false` - `search` (string) (in: query): Search by file name ## Responses ### 200: Paginated list of files with patient and order info - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `partnershipId` (string,null) **(required)**: - `uploadedByOrganizationId` (string) **(required)**: - `name` (string) **(required)**: - `type` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (number) **(required)**: - `url` (string) **(required)**: - `thumbnailUrl` (string,null) **(required)**: - `scannerSourceKey` (string,null): - `patientId` (string,null) **(required)**: - `patientName` (string,null) **(required)**: - `orderId` (string,null) **(required)**: - `orderDisplayId` (string,null) **(required)**: - `orderStatus` (string,null) **(required)**: - `uploadedBy` (string) **(required)**: - `createdAt` (string) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 401: Unauthorized — valid session required ### 404: Order not found or inaccessible ## Example ```bash curl -X GET "https://api.guidelab.co/files" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload a file `POST https://api.guidelab.co/files/upload` Uploads a small file directly via multipart form data. Large files must use the presigned upload/finalize flow. Optionally attach to a patient, order, or order item. A thumbnail can be uploaded alongside the main file. Documentation: https://docs.guidelab.co/api-reference/files/uploadFile ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 201: File uploaded and record created - `id` (string) **(required)**: - `partnershipId` (string,null) **(required)**: - `uploadedByOrganizationId` (string) **(required)**: - `name` (string) **(required)**: - `type` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (number) **(required)**: - `url` (string) **(required)**: - `thumbnailUrl` (string,null) **(required)**: - `orderId` (string,null) **(required)**: - `patientId` (string,null) **(required)**: - `orderItemId` (string,null) **(required)**: - `fileRequirementId` (string,null) **(required)**: - `createdAt` (string) **(required)**: ### 400: Missing file, invalid type, or file too large ### 401: Unauthorized — valid session required ### 409: Clinic standalone storage limit exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/files/upload" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get presigned upload URL `POST https://api.guidelab.co/files/presign` Generates a presigned PUT URL so the client can upload directly to storage. No file DB row is created until the client calls finalize after a successful upload. Optionally returns a second signed PUT URL for a thumbnail. The URLs and the finalize token stay valid for 3 hours, long enough for a 1 GiB upload on a slow connection. Documentation: https://docs.guidelab.co/api-reference/files/presignFileUpload ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `filename` (string) **(required)**: - `contentType` (string): - `size` (integer) **(required)**: - `orderId` (string): - `patientId` (string): - `orderItemId` (string): - `fileRequirementId` (string): - `fileRequirementSlotId` (string): - `treatmentPhaseId` (string): - `orderPhaseId` (string): - `orderPhaseTaskId` (string): - `type` (string): Values: `scan`, `photo`, `prescription`, `xray`, `surgical_report`, `other` - `thumbnailSize` (integer): ## Responses ### 201: Presigned upload URL(s) and finalize token returned - `fileId` (string) **(required)**: - `uploadUrl` (string) **(required)**: - `uploadContentType` (string) **(required)**: - `thumbnailUploadUrl` (string,null) **(required)**: - `thumbnailUploadContentType` (string,null) **(required)**: - `finalizeToken` (string) **(required)**: ### 400: Missing required fields, invalid file type, or file too large ### 401: Unauthorized — valid session required ### 409: Clinic standalone storage limit exceeded ### 429: Upload issuance budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/files/presign" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "filename": "string", "size": 0 }' ``` --- # Finalize a direct file upload `POST https://api.guidelab.co/files/finalize` Confirms that a previously presigned upload completed successfully, validates the stored object metadata and size, and then creates the file DB record. Documentation: https://docs.guidelab.co/api-reference/files/finalizeFileUpload ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `finalizeToken` (string) **(required)**: ## Responses ### 200: File record created or already finalized - `id` (string) **(required)**: - `partnershipId` (string,null) **(required)**: - `uploadedByOrganizationId` (string) **(required)**: - `name` (string) **(required)**: - `type` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (number) **(required)**: - `url` (string) **(required)**: - `thumbnailUrl` (string,null) **(required)**: - `orderId` (string,null) **(required)**: - `patientId` (string,null) **(required)**: - `orderItemId` (string,null) **(required)**: - `fileRequirementId` (string,null) **(required)**: - `createdAt` (string) **(required)**: ### 400: Invalid finalize token or upload is incomplete ### 401: Unauthorized — valid session required ### 403: Upload belongs to a different user ### 404: Referenced order or patient not found ### 409: Upload finalization conflicted ## Example ```bash curl -X POST "https://api.guidelab.co/files/finalize" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "finalizeToken": "string" }' ``` --- # Copy files to an order `POST https://api.guidelab.co/files/copy-to-order` Copies existing patient file objects to unique storage keys and associates the copies with a different order. Documentation: https://docs.guidelab.co/api-reference/files/copyFilesToOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `idempotency-key` (string) **(required)** (in: header): Stable key reused only when retrying the exact same command body ## Request Body Content-Type: `application/json` - `fileIds` (string[]) **(required)**: - `orderId` (string) **(required)**: - `patientId` (string): - `fileRequirementId` (string): - `fileRequirementSlotId` (string): - `treatmentPhaseId` (string): ## Responses ### 201: New file records created for the target order - `files` (object[]) **(required)**: - `id` (string) **(required)**: - `partnershipId` (string) **(required)**: - `uploadedByOrganizationId` (string) **(required)**: - `name` (string) **(required)**: - `type` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (number) **(required)**: - `url` (string) **(required)**: - `thumbnailUrl` (string,null) **(required)**: - `orderId` (string) **(required)**: - `patientId` (string,null) **(required)**: - `fileRequirementId` (string,null) **(required)**: - `createdAt` (string) **(required)**: ### 400: Invalid request body ### 401: Unauthorized — valid session required ### 404: No matching files or order not found ### 409: A file belongs to a different partnership epoch ### 413: The requested copies exceed the aggregate byte limit ### 429: Copy budget exceeded ### 502: A source object could not be copied ## Example ```bash curl -X POST "https://api.guidelab.co/files/copy-to-order" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "fileIds": [ "string" ], "orderId": "string", "patientId": "string", "fileRequirementId": "string", "fileRequirementSlotId": "string", "treatmentPhaseId": "string" }' ``` --- # Reassign files between orders `POST https://api.guidelab.co/files/reassign` Moves files from one order to another, updating order item and file requirement associations. S3 objects stay in place — only DB records are updated. Documentation: https://docs.guidelab.co/api-reference/files/reassignFiles ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `fromOrderId` (string) **(required)**: - `toOrderId` (string) **(required)**: - `assignments` (object[]) **(required)**: - `fileId` (string) **(required)**: - `orderItemId` (string,null): - `fileRequirementId` (string,null): - `treatmentPhaseId` (string,null): ## Responses ### 200: Files reassigned successfully - `success` (boolean) **(required)**: - `reassigned` (number) **(required)**: ### 400: Invalid request body ### 401: Unauthorized — valid session required ### 404: Destination order not found ### 409: A delivery-proof file cannot be reassigned ## Example ```bash curl -X POST "https://api.guidelab.co/files/reassign" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "fromOrderId": "string", "toOrderId": "string", "assignments": [ { "fileId": "string", "orderItemId": "string", "fileRequirementId": "string", "treatmentPhaseId": "string" } ] }' ``` --- # Delete a file `DELETE https://api.guidelab.co/files/{id}` Archives (soft-deletes) a file: the record and its R2 object are retained, and a retention job physically purges them after the retention window. Only an owner of the owning organization may archive; delivery-proof files are immutable, and a file attached to a non-draft order may only be archived by the organization that uploaded it. Documentation: https://docs.guidelab.co/api-reference/files/deleteFile ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): File ID ## Responses ### 200: File archived successfully - `success` (boolean) **(required)**: ### 400: File ID is required ### 401: Unauthorized — valid session required ### 403: Forbidden — owner role required ### 404: File not found or not owned by current organization ### 409: File is retained, attached to a non-draft order and uploaded by the other organization, or its partnership epoch is no longer writable ## Example ```bash curl -X DELETE "https://api.guidelab.co/files/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Download a file `GET https://api.guidelab.co/files/{id}/download` Streams the file content directly from R2 through the Worker (R2 egress is free; this avoids presigned-URL redirects and CORS surprises). Pass `?thumbnail=true` for the thumbnail variant. Documentation: https://docs.guidelab.co/api-reference/files/downloadFile ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): File ID - `preview` (string) (in: query): Values: `true`, `false` - `thumbnail` (string) (in: query): Return thumbnail variant Values: `true`, `false` ## Responses ### 200: File content streamed directly from R2 ### 401: Unauthorized — valid session required ### 404: File not found or not owned by current organization ### 429: Preview byte budget exceeded ## Example ```bash curl -X GET "https://api.guidelab.co/files/{id}/download" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List orders `GET https://api.guidelab.co/orders` Returns a paginated list of orders for the authenticated user's organization. Supports filtering by status, date range, search, and other criteria. Labs see orders where they are the lab; clinics see orders where they are the clinic. Documentation: https://docs.guidelab.co/api-reference/orders/listOrders ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Page number Default: `1` - `limit` (integer) (in: query): Items per page Default: `20` - `view` (string) (in: query): Response projection. The backward-compatible default returns the full order shape; compact omits detail-only fields for list UIs. Values: `full`, `compact` Default: `full` - `cursor` (string) (in: query): Opaque cursor returned by the previous non-search page. Send it with the matching page, filters, and sort. Search results continue to use page-based pagination. - `status` (string) (in: query): Comma-separated status filter - `type` (string) (in: query): Comma-separated order type filter (digital, physical) - `search` (string) (in: query): Search by order number, patient name, doctor name, or partner org - `sortBy` (string) (in: query): Field to sort by Values: `createdAt`, `dueDate`, `deadline`, `submittedAt`, `orderNumber`, `status` Default: `createdAt` - `sortOrder` (string) (in: query): Sort direction Values: `asc`, `desc` Default: `desc` - `clinicId` (string) (in: query): Filter by clinic ID - `patientId` (string) (in: query): Filter by patient ID - `doctorUserId` (string) (in: query): Filter by doctor user ID - `labId` (string) (in: query): Filter by lab ID - `doctorName` (string) (in: query): Filter by doctor name - `hasFiles` () (in: query): Filter orders that have files - `hasAdvanceRequest` () (in: query): Filter orders with pending phase advance requests - `upcomingDelivery` () (in: query): Filter orders whose estimated delivery falls within the next 7 days - `hasUnreadMessages` () (in: query): Filter orders with messages the viewer has not read - `needsAction` () (in: query): Clinics only: orders waiting on the clinic (an approval, a requested file re-upload, or a phase awaiting its files). Ignored for labs. - `includeAll` () (in: query): Include completed and cancelled orders. Archived orders are always excluded. Default: `false` - `withBadgeCounts` () (in: query): Include submittedCount and onHoldCount in response metadata (org-wide, unfiltered) Default: `false` ## Responses ### 200: Paginated list of orders with metadata - `data` (array) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: - `hasMore` (boolean) **(required)**: - `nextCursor` (string,null) **(required)**: ### 400: Invalid query parameters ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/orders" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get filter options for orders `GET https://api.guidelab.co/orders/filter-options` Returns available filter options for the order list, including distinct doctor names, partner organizations (labs for clinics, clinics for labs), and patients (clinics only). Used to populate filter dropdowns in the UI. Each list is capped; `truncated` reports which lists were cut short so the UI can offer a search instead of a partial dropdown. Documentation: https://docs.guidelab.co/api-reference/orders/getOrderFilterOptions ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Filter options including doctors, partners, and patients - `doctors` (string[]) **(required)**: - `patients` (object[]): - `id` (string) **(required)**: - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: - `labs` (object[]): - `id` (string) **(required)**: - `name` (string) **(required)**: - `clinics` (object[]): - `id` (string) **(required)**: - `name` (string) **(required)**: - `truncated` (object) **(required)**: - `doctors` (boolean) **(required)**: - `patients` (boolean) **(required)**: - `partners` (boolean) **(required)**: ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/orders/filter-options" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get orders needing approval `GET https://api.guidelab.co/orders/needs-approval` Returns a paginated list of submitted orders awaiting lab approval, with line items, files, work tray assignments, and unread message counts. Lab only. Supports fuzzy search across order number, PAN number, doctor name, clinic name, and patient name. Documentation: https://docs.guidelab.co/api-reference/orders/getOrdersNeedingApproval ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (string) (in: query): Page number (default: 1) - `limit` (string) (in: query): Items per page (default: 20, max: 50) - `search` (string) (in: query): Fuzzy search term ## Responses ### 200: Paginated list of submitted orders with items, files, and unread counts - `data` (array) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 401: Unauthorized ### 403: Only labs can view orders needing approval ## Example ```bash curl -X GET "https://api.guidelab.co/orders/needs-approval" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get dispatched orders `GET https://api.guidelab.co/orders/shipped` Returns orders with a dispatched shipment and every consignment associated with each order. Shipment state is independent from the canonical order lifecycle. Documentation: https://docs.guidelab.co/api-reference/orders/getShippedOrders ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `search` (string) (in: query): ## Responses ### 200: Paginated shipped orders - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `status` (string) **(required)**: Values: `draft`, `submitted`, `active`, `completed`, `cancelled`, `on_hold` - `type` (string) **(required)**: Values: `digital`, `physical` - `dueDate` (string,null) **(required)**: - `doctorName` (string,null) **(required)**: - `patient` (object,null) **(required)**: - `id` (string) **(required)**: - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: - `clinic` (object,null) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `clinicLocation` (object,null) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `items` (object) **(required)**: - `count` (integer) **(required)**: - `productNames` (string[]) **(required)**: - `shipments` (object[]) **(required)**: - `id` (string) **(required)**: - `shipmentNumber` (integer) **(required)**: - `status` (string) **(required)**: Values: `draft`, `packing`, `ready`, `in_transit`, `delivery_exception`, `delivered`, `returned`, `cancelled` - `shippingMethod` (string) **(required)**: Values: `carrier`, `local_driver` - `labels` (object[]) **(required)**: - `id` (string) **(required)**: - `packageId` (string) **(required)**: - `packageNumber` (integer) **(required)**: - `carrier` (string,null) **(required)**: - `trackingNumber` (string,null) **(required)**: - `trackingUrl` (string,null) **(required)**: [uri] - `driverName` (string,null) **(required)**: - `driverPhone` (string,null) **(required)**: - `shippedAt` (string,null) **(required)**: - `deliveredAt` (string,null) **(required)**: - `address` (string) **(required)**: - `city` (string) **(required)**: - `postcode` (string) **(required)**: - `country` (string) **(required)**: - `contactName` (string,null) **(required)**: - `contactPhone` (string,null) **(required)**: - `signedBy` (string,null) **(required)**: - `pagination` (object) **(required)**: - `page` (integer) **(required)**: - `limit` (integer) **(required)**: - `total` (integer) **(required)**: - `totalPages` (integer) **(required)**: ### 401: Unauthorized ### 403: Only labs can view shipped orders ## Example ```bash curl -X GET "https://api.guidelab.co/orders/shipped" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get calendar data `GET https://api.guidelab.co/orders/calendar` Returns calendar events grouped by date for a given date range: one delivery event per order due date and one surgery event per order surgery date (an order whose surgery day is its due date yields only the surgery event). Excludes drafts and archived orders. Supports searching by order number, patient name, doctor, or partner org. Documentation: https://docs.guidelab.co/api-reference/orders/getOrderCalendar ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `startDate` (string) **(required)** (in: query): Start date (YYYY-MM-DD) - `endDate` (string) **(required)** (in: query): End date (YYYY-MM-DD) - `search` (string) (in: query): Search term for order number, patient, doctor, or org name ## Responses ### 200: Calendar data grouped by date with order counts and summaries - `days` (object) **(required)**: - `total` (number) **(required)**: - `orders` (object[]) **(required)**: - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `patientName` (string,null) **(required)**: - `status` (string) **(required)**: - `kind` (string) **(required)**: Values: `delivery`, `surgery` - `actionTypes` (string[]): Clinic only: the order's pending dashboard tasks for the requesting member. ### 400: Invalid query parameters - dates must be YYYY-MM-DD format ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/orders/calendar" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get orders for a specific day `GET https://api.guidelab.co/orders/calendar/day` Returns a paginated list of orders whose due date or surgery date falls on a specific date, with full order details including phase summaries. Supports filtering by status and search. Used for the day detail view in the calendar. Documentation: https://docs.guidelab.co/api-reference/orders/getOrderCalendarDay ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `date` (string) **(required)** (in: query): Date (YYYY-MM-DD) - `status` (string) (in: query): Comma-separated status filter - `search` (string) (in: query): Search term - `page` (string) (in: query): Page number (default: 1) - `limit` (string) (in: query): Items per page (default: 20, max: 100) ## Responses ### 200: Paginated list of orders for the day with phase summaries - `data` (array) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/orders/calendar/day" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get most recent draft order `GET https://api.guidelab.co/orders/drafts` Returns the most recent draft order created by the authenticated user within their organization. Includes related clinic, lab, patient, and line item data. Returns null if no draft exists. Documentation: https://docs.guidelab.co/api-reference/orders/getMostRecentDraft ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Most recent draft order with related data, or null if none exists - `draft` (object): ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/orders/drafts" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create draft order `POST https://api.guidelab.co/orders/drafts` Creates a new draft order with optional line items and wizard state for multi-step order creation. The draft is owned by the authenticated user and can be resumed later. Documentation: https://docs.guidelab.co/api-reference/orders/createDraftOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `clinicId` (string): - `labId` (string): - `clinicLocationId` (string): - `patientId` (string): - `doctorName` (string): - `doctorEmail` (object): - `doctorPhone` (string): - `type` (string): (default: `digital`) Values: `digital`, `physical` - `receivingSourceId` (string,null): - `scannerType` (string): - `dueDate` (string): - `surgeryDate` (string): - `notes` (string): - `hidePatientFromLab` (boolean): (default: `false`) - `shippingTypeId` (string,null): - `shippingInsured` (boolean): - `shipWithOrderId` (string,null): - `items` (object[]): (default: ``) - `productId` (string,null) **(required)**: - `toothGroups` (object[]): (default: ``) - `id` (string) **(required)**: - `type` (string) **(required)**: Values: `single`, `bridge` - `teeth` (object[]) **(required)**: - `fdi` (integer) **(required)**: - `role` (string) **(required)**: Values: `crown`, `pontic` - `support` (string): Values: `natural`, `implant` - `implantSystemId` (string): - `implantPlatform` (string): - `quantity` (integer): (default: `1`) - `materialId` (string): - `material` (string): (default: ``) - `shadeSystemId` (string): - `shadeOcclusal` (string): (default: ``) - `shadeMiddle` (string): (default: ``) - `shadeGingival` (string): (default: ``) - `defaultImplantSystemId` (string): - `defaultImplantPlatform` (string): - `notes` (string): (default: ``) - `customFieldValues` (object): - `value` (object): - `fileIds` (string[]): - `bundleId` (string): - `bundleInstanceId` (string): - `bundleName` (string): - `bundlePrice` (string): - `wizardState` (object): - `step` (number) **(required)**: - `categoryId` (string): - `categoryName` (string): - `phasesToStart` (string[]): - `phaseNeededBy` (object): - `issueId` (string): - `remakeReasonId` (string): ## Responses ### 201: Created draft order ID and order number - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: ### 400: Validation failed, or a line item references a product, material, shade system, implant system or bundle that is not available for the destination lab ### 401: Unauthorized ## Example ```bash curl -X POST "https://api.guidelab.co/orders/drafts" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Get specific draft order `GET https://api.guidelab.co/orders/drafts/{id}` Returns a specific draft order by ID, including related clinic, lab, patient, line items, and attached files. Only accessible by the draft creator within their organization. Documentation: https://docs.guidelab.co/api-reference/orders/getDraftById ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Draft order ID ## Responses ### 200: Draft order with items, files, and related data, or null if not found - `draft` (object): ### 400: Draft ID is required ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/orders/drafts/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update draft order `PATCH https://api.guidelab.co/orders/drafts/{id}` Updates an existing draft order's fields and optionally replaces all line items. Only the organization that created the draft can update it. Supports updating wizard state for multi-step order flows. Changing clinicId or labId replaces the line items with `items` (none when omitted), archives the draft's files, detaches its conversation and other links, and moves a new lab's draft to that lab's currency. Documentation: https://docs.guidelab.co/api-reference/orders/updateDraftOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Draft order ID ## Request Body Content-Type: `application/json` - `clinicId` (string): - `labId` (string): - `clinicLocationId` (string): - `patientId` (string): - `doctorName` (string): - `doctorEmail` (object): - `doctorPhone` (string): - `type` (string): Values: `digital`, `physical` - `receivingSourceId` (string,null): - `scannerType` (string): - `dueDate` (string,null): - `surgeryDate` (string,null): - `notes` (string): - `hidePatientFromLab` (boolean): - `shippingTypeId` (string,null): - `shippingInsured` (boolean): - `shipWithOrderId` (string,null): - `items` (object[]): - `productId` (string,null) **(required)**: - `toothGroups` (object[]): (default: ``) - `id` (string) **(required)**: - `type` (string) **(required)**: Values: `single`, `bridge` - `teeth` (object[]) **(required)**: - `fdi` (integer) **(required)**: - `role` (string) **(required)**: Values: `crown`, `pontic` - `support` (string): Values: `natural`, `implant` - `implantSystemId` (string): - `implantPlatform` (string): - `quantity` (integer): (default: `1`) - `materialId` (string): - `material` (string): (default: ``) - `shadeSystemId` (string): - `shadeOcclusal` (string): (default: ``) - `shadeMiddle` (string): (default: ``) - `shadeGingival` (string): (default: ``) - `defaultImplantSystemId` (string): - `defaultImplantPlatform` (string): - `notes` (string): (default: ``) - `customFieldValues` (object): - `value` (object): - `fileIds` (string[]): - `bundleId` (string): - `bundleInstanceId` (string): - `bundleName` (string): - `bundlePrice` (string): - `wizardState` (object): - `step` (number) **(required)**: - `categoryId` (string): - `categoryName` (string): - `phasesToStart` (string[]): - `phaseNeededBy` (object): - `issueId` (string): - `remakeReasonId` (string): ## Responses ### 200: Confirmation that the draft was updated - `success` (boolean) **(required)**: ### 400: Validation failed, or a line item references a product, material, shade system, implant system or bundle that is not available for the destination lab ### 401: Unauthorized ### 404: Draft not found or not accessible ### 409: The draft is locked by an in-progress payment (DRAFT_PAYMENT_FENCED), changed underneath the request, or cannot change lab or clinic because a record such as a scan booking or scanner import still holds it (DRAFT_HAS_LINKED_RECORDS). A client must not retry the same body: the payment fence is released only by cancelling the payment. ## Example ```bash curl -X PATCH "https://api.guidelab.co/orders/drafts/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Delete draft order `DELETE https://api.guidelab.co/orders/drafts/{id}` Permanently deletes a draft order and archives its clinical file records for durable retention cleanup. R2 objects remain tracked until the retention worker confirms deletion. Documentation: https://docs.guidelab.co/api-reference/orders/deleteDraftOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Draft order ID ## Responses ### 200: Confirmation that the draft was deleted - `success` (boolean) **(required)**: ### 400: Draft ID is required ### 401: Unauthorized ### 403: Forbidden ### 404: Draft not found or not accessible ### 409: Draft changed (DRAFT_CHANGED), is locked by a payment attempt (DRAFT_PAYMENT_FENCED), contains delivery-proof evidence (DRAFT_DELIVERY_PROOF), is scanner-booked (DRAFT_SCANNER_BOOKED), or still holds a linked record such as a shipment, payment or retention hold (DRAFT_HAS_LINKED_RECORDS) ## Example ```bash curl -X DELETE "https://api.guidelab.co/orders/drafts/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # The lab's problem reports, newest first `GET https://api.guidelab.co/orders/issues` Documentation: https://docs.guidelab.co/api-reference/orders/listLabOrderIssues ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `status` (string) (in: query): Values: `open`, `closed` - `page` (integer) (in: query): Default: `1` - `pageSize` (integer) (in: query): Default: `25` ## Responses ### 200: One page of the lab's reports - `issues` (object[]) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string) **(required)**: - `clinicName` (string) **(required)**: - `channel` (string) **(required)**: Values: `app`, `phone`, `email`, `whatsapp`, `in_person`, `returned_device` - `category` (string) **(required)**: Values: `breakage`, `fit`, `aesthetic`, `discomfort`, `wrong_specification`, `other` - `patientHarm` (string) **(required)**: Values: `none`, `non_serious`, `serious` - `status` (string) **(required)**: Values: `open`, `closed` - `resolution` (string,null) **(required)**: Values: `remake`, `repair`, `adjustment`, `information`, `no_action`, `null` - `createdAt` (string) **(required)**: - `closedAt` (string,null) **(required)**: - `total` (integer) **(required)**: - `page` (integer) **(required)**: - `pageSize` (integer) **(required)**: ### 403: Only labs keep the complaint register - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/orders/issues" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Problem reports on an order `GET https://api.guidelab.co/orders/{id}/issues` The lab and the order's clinic both read the reports. A clinic never receives the root cause, the investigation or the corrective action. For the lab, an open report of serious harm adds the vigilance facts of its jurisdiction. Documentation: https://docs.guidelab.co/api-reference/orders/listOrderIssues ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Reports, newest first - `issues` (object[]) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderItemId` (string,null) **(required)**: - `channel` (string) **(required)**: Values: `app`, `phone`, `email`, `whatsapp`, `in_person`, `returned_device` - `category` (string) **(required)**: Values: `breakage`, `fit`, `aesthetic`, `discomfort`, `wrong_specification`, `other` - `description` (string) **(required)**: - `detectedOn` (string,null) **(required)**: - `patientHarm` (string) **(required)**: Values: `none`, `non_serious`, `serious` - `requestedAction` (string,null) **(required)**: Values: `repair`, `remake`, `adjustment`, `information`, `null` - `status` (string) **(required)**: Values: `open`, `closed` - `resolution` (string,null) **(required)**: Values: `remake`, `repair`, `adjustment`, `information`, `no_action`, `null` - `reply` (string,null) **(required)**: - `rootCause` (string,null): Values: `prescription_impression`, `patient_use`, `manufacturing`, `material`, `undetermined`, `null` - `investigation` (string,null): - `correctiveAction` (string,null): - `replacementOrderId` (string,null) **(required)**: - `reportedByName` (string,null) **(required)**: - `fileIds` (string[]) **(required)**: - `closedAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `vigilance` (object,null) **(required)**: - `authority` (string) **(required)**: - `reporting` (string) **(required)**: - `deadlines` (string) **(required)**: - `sources` (string[]) **(required)**: ### 404: Order not found - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/issues" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Report a problem with a delivered order `POST https://api.guidelab.co/orders/{id}/issues` The order's clinic reports in the app (the channel is always `app`) while its partnership is active; lab staff log a report that reached them another way and name the channel. A clinic report notifies the lab's owners and admins. At most 50 reports per clinic per day. Documentation: https://docs.guidelab.co/api-reference/orders/createOrderIssue ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `channel` (string): Values: `app`, `phone`, `email`, `whatsapp`, `in_person`, `returned_device` - `category` (string) **(required)**: Values: `breakage`, `fit`, `aesthetic`, `discomfort`, `wrong_specification`, `other` - `description` (string) **(required)**: - `detectedOn` (string,null): (default: `null`) - `patientHarm` (string): (default: `none`) Values: `none`, `non_serious`, `serious` - `requestedAction` (string,null): (default: `null`) Values: `repair`, `remake`, `adjustment`, `information`, `null` - `orderItemId` (string,null): (default: `null`) - `fileIds` (string[]): (default: ``) ## Responses ### 201: The report - `issue` (object) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderItemId` (string,null) **(required)**: - `channel` (string) **(required)**: Values: `app`, `phone`, `email`, `whatsapp`, `in_person`, `returned_device` - `category` (string) **(required)**: Values: `breakage`, `fit`, `aesthetic`, `discomfort`, `wrong_specification`, `other` - `description` (string) **(required)**: - `detectedOn` (string,null) **(required)**: - `patientHarm` (string) **(required)**: Values: `none`, `non_serious`, `serious` - `requestedAction` (string,null) **(required)**: Values: `repair`, `remake`, `adjustment`, `information`, `null` - `status` (string) **(required)**: Values: `open`, `closed` - `resolution` (string,null) **(required)**: Values: `remake`, `repair`, `adjustment`, `information`, `no_action`, `null` - `reply` (string,null) **(required)**: - `rootCause` (string,null): Values: `prescription_impression`, `patient_use`, `manufacturing`, `material`, `undetermined`, `null` - `investigation` (string,null): - `correctiveAction` (string,null): - `replacementOrderId` (string,null) **(required)**: - `reportedByName` (string,null) **(required)**: - `fileIds` (string[]) **(required)**: - `closedAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Missing channel, or an item or file of another order - `error` (string) **(required)**: ### 404: Order not found - `error` (string) **(required)**: ### 409: The order is not delivered, or the partnership is read-only - `error` (string) **(required)**: ### 429: Daily report limit reached for this clinic - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/issues" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "category": "breakage", "description": "string" }' ``` --- # Investigate, answer, close or reopen a report `PATCH https://api.guidelab.co/orders/{id}/issues/{issueId}` Lab only. `status: "closed"` needs a resolution and notifies the clinic; `status: "open"` reopens a closed report. Documentation: https://docs.guidelab.co/api-reference/orders/updateOrderIssue ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `issueId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `patientHarm` (string): Values: `none`, `non_serious`, `serious` - `requestedAction` (string,null): Values: `repair`, `remake`, `adjustment`, `information`, `null` - `rootCause` (string,null): Values: `prescription_impression`, `patient_use`, `manufacturing`, `material`, `undetermined`, `null` - `investigation` (string,null): - `correctiveAction` (string,null): - `reply` (string,null): - `status` (string): Values: `open`, `closed` - `resolution` (string): Values: `remake`, `repair`, `adjustment`, `information`, `no_action` ## Responses ### 200: The report - `issue` (object) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderItemId` (string,null) **(required)**: - `channel` (string) **(required)**: Values: `app`, `phone`, `email`, `whatsapp`, `in_person`, `returned_device` - `category` (string) **(required)**: Values: `breakage`, `fit`, `aesthetic`, `discomfort`, `wrong_specification`, `other` - `description` (string) **(required)**: - `detectedOn` (string,null) **(required)**: - `patientHarm` (string) **(required)**: Values: `none`, `non_serious`, `serious` - `requestedAction` (string,null) **(required)**: Values: `repair`, `remake`, `adjustment`, `information`, `null` - `status` (string) **(required)**: Values: `open`, `closed` - `resolution` (string,null) **(required)**: Values: `remake`, `repair`, `adjustment`, `information`, `no_action`, `null` - `reply` (string,null) **(required)**: - `rootCause` (string,null): Values: `prescription_impression`, `patient_use`, `manufacturing`, `material`, `undetermined`, `null` - `investigation` (string,null): - `correctiveAction` (string,null): - `replacementOrderId` (string,null) **(required)**: - `reportedByName` (string,null) **(required)**: - `fileIds` (string[]) **(required)**: - `closedAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 403: Only the lab updates a report - `error` (string) **(required)**: ### 404: Order or report not found - `error` (string) **(required)**: ## Example ```bash curl -X PATCH "https://api.guidelab.co/orders/{id}/issues/{issueId}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Bulk delete or cancel orders `POST https://api.guidelab.co/orders/bulk-delete` Processes a batch of order IDs in a single request. Drafts are deleted while their clinical files are archived for durable retention cleanup; non-draft orders are cancelled. Each order is processed independently. Documentation: https://docs.guidelab.co/api-reference/orders/bulkDeleteOrders ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `ids` (string[]) **(required)**: ## Responses ### 200: Counts of deleted/cancelled orders and per-id errors - `deleted` (number) **(required)**: - `cancelled` (number) **(required)**: - `total` (number) **(required)**: - `errors` (object[]) **(required)**: - `id` (string) **(required)**: - `error` (string) **(required)**: ### 400: Invalid request body ### 401: Unauthorized ## Example ```bash curl -X POST "https://api.guidelab.co/orders/bulk-delete" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "ids": [ "string" ] }' ``` --- # Cancel an order with an explicit refund decision `POST https://api.guidelab.co/orders/{id}/cancel` Cancels an order. Paid orders require a lab owner/admin to choose a full, partial, or no refund and provide a reason. Stripe direct-charge refunds are committed only after provider confirmation. Documentation: https://docs.guidelab.co/api-reference/orders/cancelOrderWithRefundChoice ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `idempotencyKey` (string) **(required)**: - `reason` (string) **(required)**: - `refundMode` (string) **(required)**: Values: `none`, `full`, `partial` - `refundAmount` (string): ## Responses ### 200: Order cancelled - `message` (string) **(required)**: - `refund` (object) **(required)**: - `mode` (string) **(required)**: Values: `none`, `full`, `partial` - `status` (string) **(required)**: Values: `not_requested`, `pending`, `succeeded`, `failed` - `refundId` (string,null) **(required)**: - `amount` (string,null) **(required)**: - `currency` (string) **(required)**: ### 202: Refund is pending provider confirmation - `message` (string) **(required)**: - `refund` (object) **(required)**: - `mode` (string) **(required)**: Values: `none`, `full`, `partial` - `status` (string) **(required)**: Values: `not_requested`, `pending`, `succeeded`, `failed` - `refundId` (string,null) **(required)**: - `amount` (string,null) **(required)**: - `currency` (string) **(required)**: ### 400: Invalid cancellation or refund amount ### 401: Unauthorized ### 403: Lab owner or admin access is required ### 404: Order or paid receipt not found ### 409: Order or idempotency state conflicts ### 502: Stripe could not confirm the refund ### 503: Stripe is not configured safely ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/cancel" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "idempotencyKey": "string", "reason": "string", "refundMode": "none", "refundAmount": "string" }' ``` --- # Get order by ID `GET https://api.guidelab.co/orders/{id}` Returns full order details including line items, phases, status history, phase step history, production tasks (lab only), and active hold information. Patient data is masked for labs when hidePatientFromLab is enabled. Documentation: https://docs.guidelab.co/api-reference/orders/getOrderDetail ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Responses ### 200: Full order details with items, phases, history, tasks, and active hold - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `status` (string) **(required)**: - `submittedAt` (string,null) **(required)**: - `items` (array) **(required)**: - `phases` (array) **(required)**: - `statusHistory` (array) **(required)**: - `phaseStepHistory` (array) **(required)**: - `tasks` (array,null) **(required)**: - `activeHold` (object): - `shipping` (object,null) **(required)**: - `shippingTypeId` (string,null) **(required)**: - `name` (string) **(required)**: - `method` (string,null) **(required)**: Values: `carrier`, `local_driver`, `collection`, `null` - `amount` (string) **(required)**: - `insuranceAmount` (string) **(required)**: - `totalAmount` (string) **(required)**: - `group` (object,null) **(required)**: - `anchorOrderId` (string) **(required)**: - `orders` (object[]) **(required)**: - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `status` (string) **(required)**: Values: `draft`, `submitted`, `active`, `completed`, `cancelled`, `on_hold` - `shippingLab` (object,null) **(required)**: Lab only; null for clinics - `weightGrams` (integer,null) **(required)**: - `missingWeightCount` (integer) **(required)**: - `zoneName` (string,null) **(required)**: - `notCharged` (boolean) **(required)**: - `editable` (boolean) **(required)**: ### 400: Order ID is required ### 401: Unauthorized ### 404: Order not found or not accessible by the current organization ### 500: Submitted order catalog revision is invalid ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update order `PATCH https://api.guidelab.co/orders/{id}` Updates order fields such as patient, doctor, dates, notes, and assignment. Labs can update any accessible order; clinics can only update orders in draft status. Assigning a user triggers a notification and auto-subscribes them. Documentation: https://docs.guidelab.co/api-reference/orders/updateOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Request Body Content-Type: `application/json` - `clinicLocationId` (string,null): - `patientId` (string,null): - `doctorUserId` (string,null): - `doctorName` (string): - `doctorPhone` (string): - `doctorEmail` (object): - `type` (string): Values: `digital`, `physical` - `receivingSourceId` (string,null): - `scannerType` (string): - `panNumber` (string): - `manualFilePath` (string,null): - `deadline` (string,null): - `dueDate` (string,null): - `notes` (string): - `internalNotes` (string): - `assignedToMemberId` (string,null): ## Responses ### 200: Updated order record - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `status` (string) **(required)**: ### 400: Validation failed ### 401: Unauthorized ### 403: Only the destination lab can assign an order ### 404: Order not found or cannot be edited ### 500: Destination lab configuration is invalid ## Example ```bash curl -X PATCH "https://api.guidelab.co/orders/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Cancel order `DELETE https://api.guidelab.co/orders/{id}` Cancels an order by setting its status to 'cancelled' and recording a status history entry. Labs can cancel any of their orders; clinics can only cancel orders in draft status. Documentation: https://docs.guidelab.co/api-reference/orders/cancelOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Responses ### 200: Confirmation that the order was cancelled - `message` (string) **(required)**: ### 400: Order ID is required ### 401: Unauthorized ### 404: Order not found or cannot be deleted ### 409: Paid order requires the explicit cancellation flow ## Example ```bash curl -X DELETE "https://api.guidelab.co/orders/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update order status `PATCH https://api.guidelab.co/orders/{id}/status` Transitions an existing submitted order with validation of allowed transitions. Draft submission is owned exclusively by POST /orders/:id/submit so phase materialization and promotion remain atomic. Documentation: https://docs.guidelab.co/api-reference/orders/updateOrderStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Request Body Content-Type: `application/json` - `status` (string) **(required)**: Values: `draft`, `submitted`, `active`, `completed`, `cancelled`, `on_hold` - `notes` (string): ## Responses ### 200: Updated order with full status history - `order` (object): - `statusHistory` (object[]) **(required)**: - `id` (string) **(required)**: - `fromStatus` (string,null) **(required)**: - `toStatus` (string) **(required)**: - `changedBy` (string,null) **(required)**: - `changedByName` (string,null) **(required)**: - `changedByActorKind` (string) **(required)**: Values: `system`, `user`, `anonymized_user` - `notes` (string,null) **(required)**: - `createdAt` (string) **(required)**: ### 400: Invalid status transition or incomplete phases for completion ### 401: Unauthorized ### 403: Clinics cannot perform this status transition ### 404: Order not found ### 409: Partnership/status conflict, insufficient inventory for completion, or leaving on_hold during an open surgical-report/CAD review ## Example ```bash curl -X PATCH "https://api.guidelab.co/orders/{id}/status" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "status": "draft", "notes": "string" }' ``` --- # Submit an existing order draft `POST https://api.guidelab.co/orders/{id}/submit` Atomically validates and promotes a draft created by the caller's organization in place. Replays return the same order when submitted_at proves a prior successful submission. A rejection may carry a machine-readable `code` from the order payment error codes, and a catalog rejection lists the offending `details.productIds`. Documentation: https://docs.guidelab.co/api-reference/orders/submitDraftOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Existing draft order ID ## Responses ### 200: The existing order draft was submitted or replayed - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `replayed` (boolean) **(required)**: ### 400: Draft or catalog validation failed ### 401: Unauthorized ### 402: The destination lab cannot receive new work ### 404: Draft not found or not accessible ### 409: Draft lifecycle, partnership, or payment policy changed during submission ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/submit" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get order status history `GET https://api.guidelab.co/orders/{id}/status-history` Returns the complete status transition history for an order, plus the phase-change history, sourced from the unified orderActivity log. Documentation: https://docs.guidelab.co/api-reference/orders/getOrderStatusHistory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Responses ### 200: Order status and phase change history with change details - `statusHistory` (object[]) **(required)**: - `id` (string) **(required)**: - `fromStatus` (string,null) **(required)**: - `toStatus` (string) **(required)**: - `changedBy` (string,null) **(required)**: - `changedByName` (string,null) **(required)**: - `changedByActorKind` (string) **(required)**: Values: `system`, `user`, `anonymized_user` - `notes` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `phaseStepHistory` (object[]) **(required)**: - `id` (string) **(required)**: - `phaseName` (string,null) **(required)**: - `fromPhase` (string,null) **(required)**: - `toPhase` (string) **(required)**: - `changedBy` (string,null) **(required)**: - `changedByName` (string,null) **(required)**: - `changedByActorKind` (string) **(required)**: Values: `system`, `user`, `anonymized_user` - `notes` (string,null) **(required)**: - `createdAt` (string) **(required)**: ### 400: Order ID is required ### 401: Unauthorized ### 404: Order not found or not accessible by the current organization ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/status-history" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Put order on hold `POST https://api.guidelab.co/orders/{id}/hold` Places an order on hold with a specified hold reason from the lab's configured reasons. Optionally creates file reupload requirements if the hold reason requires it. Only labs can put orders on hold. Sends a notification to the clinic. Documentation: https://docs.guidelab.co/api-reference/orders/createOrderHold ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Request Body Content-Type: `application/json` - `holdReasonId` (string) **(required)**: - `notes` (string): - `fileIds` (string[]): ## Responses ### 200: Created hold record with file reupload requirements - `hold` (object): - `requirements` (array) **(required)**: ### 400: Invalid status transition or file validation failed ### 401: Unauthorized ### 403: Only labs can put orders on hold ### 404: Order or hold reason not found ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/hold" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "holdReasonId": "string", "notes": "string", "fileIds": [ "string" ] }' ``` --- # Get hold requirements for order `GET https://api.guidelab.co/orders/{id}/hold-requirements` Returns the active hold and its file reupload requirements for an order. Accessible by both labs and clinics with access to the order. Returns null if no active hold exists. Documentation: https://docs.guidelab.co/api-reference/orders/getOrderHoldRequirements ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Responses ### 200: Active hold with file reupload requirements, or null if no active hold - `hold` (object,null) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `holdReasonName` (string) **(required)**: - `notes` (string,null) **(required)**: - `previousStatus` (string) **(required)**: - `status` (string) **(required)**: - `createdAt` (string) **(required)**: - `requirements` (array) **(required)**: - `requirements` (array) **(required)**: ### 400: Order ID is required ### 401: Unauthorized ### 404: Order not found or not accessible by the current organization ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/hold-requirements" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Review hold requirement `POST https://api.guidelab.co/orders/{id}/hold-requirements/{requirementId}/review` Approves or rejects a submitted hold requirement. Only labs can review requirements. When all requirements are approved, the hold is automatically resolved and the order resumes its previous status. Documentation: https://docs.guidelab.co/api-reference/orders/reviewHoldRequirement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID - `requirementId` (string) **(required)** (in: path): Hold requirement ID ## Request Body Content-Type: `application/json` - `decision` (string) **(required)**: Values: `approved`, `rejected` - `notes` (string): ## Responses ### 200: Review result including whether all requirements are approved and order auto-resumed - `success` (boolean) **(required)**: - `allApproved` (boolean) **(required)**: - `autoResumed` (boolean) **(required)**: ### 400: Requirement is not in submitted state ### 401: Unauthorized ### 403: Only labs can review hold requirements ### 404: Order, requirement, or hold record not found ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/hold-requirements/{requirementId}/review" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "decision": "approved", "notes": "string" }' ``` --- # Submit hold requirement `POST https://api.guidelab.co/orders/{id}/hold-requirements/{requirementId}/submit` Submits a file to fulfill a hold requirement. Only clinics can submit hold requirements. Supports resubmission after rejection. Sends a notification to the lab for review. Documentation: https://docs.guidelab.co/api-reference/orders/submitHoldRequirement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID - `requirementId` (string) **(required)** (in: path): Hold requirement ID ## Request Body Content-Type: `application/json` - `fileId` (string) **(required)**: ## Responses ### 200: Confirmation that the requirement was submitted - `success` (boolean) **(required)**: ### 400: Requirement is not in a state that accepts submissions ### 401: Unauthorized ### 403: Only clinics can submit hold requirements ### 404: Order, requirement, or file not found ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/hold-requirements/{requirementId}/submit" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "fileId": "string" }' ``` --- # List tasks of an order's current phase `GET https://api.guidelab.co/orders/{orderId}/phase-tasks` Returns the ordered task list of the order's active phase. For clinic requesters, only clinic-visible entries are returned and labels resolve to clinicTitle when set. Documentation: https://docs.guidelab.co/api-reference/orders/listOrderPhaseTasks ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `orderId` (string) **(required)** (in: path): ## Responses ### 200: Phase tasks - `tasks` (object[]) **(required)**: - `id` (string) **(required)**: - `taskId` (string) **(required)**: - `label` (string) **(required)**: - `sortOrder` (integer) **(required)**: - `isCurrent` (boolean) **(required)**: ### 401: Unauthorized ### 404: Order not found ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{orderId}/phase-tasks" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Request phase advancement (clinic only) `POST https://api.guidelab.co/orders/{id}/phases/{phaseId}/request-advance` Allows a clinic to submit files for a phase and ask the lab to begin work. Sets filesSubmitted and points currentPhaseTaskId at the phase's first task. Documentation: https://docs.guidelab.co/api-reference/orders/requestOrderPhaseAdvance ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID - `phaseId` (string) **(required)** (in: path): Order phase ID ## Responses ### 200: Confirmation that the phase advance was requested - `success` (boolean) **(required)**: ### 400: Files already submitted or no tasks configured for this phase ### 401: Unauthorized ### 403: Only clinics can request phase advancement ### 404: Order or phase not found ### 409: Order or phase state changed while updating ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/phases/{phaseId}/request-advance" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Assign or unassign a work tray to a stage (lab only) `PATCH https://api.guidelab.co/orders/{id}/phases/{phaseId}/work-tray` Sets orderPhase.workTrayId for one stage. A tray can occupy at most one active stage at a time; pass null workTrayId to unassign. Documentation: https://docs.guidelab.co/api-reference/orders/assignOrderPhaseWorkTray ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `phaseId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `workTrayId` (string,null) **(required)**: ## Responses ### 200: Assigned - `workTrayId` (string,null) **(required)**: - `workTray` (object,null) **(required)**: - `id` (string) **(required)**: - `code` (string) **(required)**: - `color` (string,null) **(required)**: - `taskAdvanced` (boolean) **(required)**: - `taskBlockedReason` (string,null) **(required)**: Values: `no_tray_task`, `needs_operator_input`, `fire_failed`, `null` ### 403: Only labs can assign trays ### 404: Order, stage, or tray not found ### 409: Tray already assigned to another stage - `error` (string) **(required)**: - `conflict` (object): - `orderPhaseId` (string) **(required)**: - `phaseName` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string) **(required)**: - `sameOrder` (boolean) **(required)**: ## Example ```bash curl -X PATCH "https://api.guidelab.co/orders/{id}/phases/{phaseId}/work-tray" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "workTrayId": "string" }' ``` --- # Get an order's revision-aware QC state `GET https://api.guidelab.co/orders/{id}/qc` Documentation: https://docs.guidelab.co/api-reference/orders/getOrderQc ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `historyLimit` (integer) (in: query): Default: `10` ## Responses ### 200: QC configuration, current gate state, and bounded history - `qcEnabled` (boolean) **(required)**: - `selectAllEnabled` (boolean) **(required)**: - `fulfillmentRevision` (integer) **(required)**: - `gatePassed` (boolean) **(required)**: - `checklist` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `sortOrder` (integer) **(required)**: - `latestInspection` (object,null) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderRevision` (integer) **(required)**: - `attemptNumber` (integer) **(required)**: - `outcome` (string) **(required)**: Values: `passed`, `failed` - `notes` (string,null) **(required)**: - `completedByUserId` (string,null) **(required)**: - `completedByName` (string,null) **(required)**: - `completedAt` (string) **(required)**: - `results` (object[]) **(required)**: - `checklistItemId` (string) **(required)**: - `itemName` (string) **(required)**: - `passed` (boolean) **(required)**: - `notes` (string,null) **(required)**: - `history` (object[]) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderRevision` (integer) **(required)**: - `attemptNumber` (integer) **(required)**: - `outcome` (string) **(required)**: Values: `passed`, `failed` - `notes` (string,null) **(required)**: - `completedByUserId` (string,null) **(required)**: - `completedByName` (string,null) **(required)**: - `completedAt` (string) **(required)**: - `results` (object[]) **(required)**: - `checklistItemId` (string) **(required)**: - `itemName` (string) **(required)**: - `passed` (boolean) **(required)**: - `notes` (string,null) **(required)**: ### 401: Unauthorized ### 403: Lab access required ### 404: Order not found ### 409: QC checklist exceeds its bounded execution limit ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/qc" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Record an immutable QC inspection `POST https://api.guidelab.co/orders/{id}/qc` Documentation: https://docs.guidelab.co/api-reference/orders/completeOrderQc ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `results` (object[]) **(required)**: - `checklistItemId` (string) **(required)**: - `passed` (boolean) **(required)**: - `notes` (string,null): - `notes` (string,null): ## Responses ### 201: QC inspection recorded - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderRevision` (integer) **(required)**: - `attemptNumber` (integer) **(required)**: - `outcome` (string) **(required)**: Values: `passed`, `failed` - `notes` (string,null) **(required)**: - `completedByUserId` (string,null) **(required)**: - `completedByName` (string,null) **(required)**: - `completedAt` (string) **(required)**: - `results` (object[]) **(required)**: - `checklistItemId` (string) **(required)**: - `itemName` (string) **(required)**: - `passed` (boolean) **(required)**: - `notes` (string,null) **(required)**: ### 400: Checklist result set is incomplete or invalid ### 401: Unauthorized ### 403: Lab access required ### 404: Order not found ### 409: QC is disabled or order is not active ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/qc" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "results": [ { "checklistItemId": "string", "passed": true, "notes": "string" } ], "notes": "string" }' ``` --- # Get current surgical report review state `GET https://api.guidelab.co/orders/{id}/surgical-report` Returns the immutable revisions and review timeline for the active surgical report hold. Documentation: https://docs.guidelab.co/api-reference/orders/getCurrentSurgicalReport ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Current surgical report state - `blockedByOtherHold` (boolean) **(required)**: - `review` (object,null) **(required)**: - `reviewId` (string) **(required)**: - `holdId` (string) **(required)**: - `orderPhaseId` (string) **(required)**: - `orderPhaseTaskId` (string) **(required)**: - `status` (string) **(required)**: Values: `pending_review`, `changes_requested`, `approved` - `currentRevisionNumber` (integer) **(required)**: - `reviewNotes` (string,null) **(required)**: - `bookingUrl` (string,null) **(required)**: - `reviewedAt` (string,null) **(required)**: - `currentRevision` (object) **(required)**: - `id` (string) **(required)**: - `revisionNumber` (integer) **(required)**: - `projectUrl` (string,null) **(required)**: - `submittedByMemberId` (string) **(required)**: - `submittedAt` (string) **(required)**: - `files` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `type` (string) **(required)**: - `category` (string) **(required)**: Values: `report`, `extra` - `sortOrder` (integer) **(required)**: - `revisions` (object[]) **(required)**: - `id` (string) **(required)**: - `revisionNumber` (integer) **(required)**: - `projectUrl` (string,null) **(required)**: - `submittedByMemberId` (string) **(required)**: - `submittedAt` (string) **(required)**: - `files` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `type` (string) **(required)**: - `category` (string) **(required)**: Values: `report`, `extra` - `sortOrder` (integer) **(required)**: - `events` (object[]) **(required)**: - `id` (string) **(required)**: - `sequence` (integer) **(required)**: - `eventType` (string) **(required)**: Values: `submitted`, `resubmitted`, `changes_requested`, `approved` - `revisionId` (string) **(required)**: - `actorMemberId` (string) **(required)**: - `notes` (string,null) **(required)**: - `createdAt` (string) **(required)**: ### 401: Unauthorized ### 404: Order not found ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/surgical-report" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Approve surgical report (clinic only) `POST https://api.guidelab.co/orders/{id}/surgical-report/{reviewId}/approve` Approves the current immutable revision with the clinic doctor's signed authorization to proceed, completes the approval task, resolves its hold, resumes production, and attaches the signed authorization PDF to the order. Documentation: https://docs.guidelab.co/api-reference/orders/approveSurgicalReport ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `reviewId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `commandId` (string) **(required)**: [uuid] - `authorization` (object) **(required)**: - `signerName` (string) **(required)**: - `accepted` (boolean) **(required)**: Values: `true` - `language` (string) **(required)**: Values: `en`, `es`, `it`, `zh` ## Responses ### 200: Approval result - `success` (boolean) **(required)**: - `autoResumed` (boolean) **(required)**: - `replayed` (boolean) **(required)**: ### 401: Unauthorized ### 403: Only clinic members can approve reviews ### 404: Order or review not found ### 409: Review or command conflict ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/surgical-report/{reviewId}/approve" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "commandId": "string", "authorization": { "signerName": "string", "accepted": true, "language": "en" } }' ``` --- # Request a new surgical report revision (clinic only) `POST https://api.guidelab.co/orders/{id}/surgical-report/{reviewId}/request-changes` Keeps the approval task and hold open while requiring the lab to submit a new immutable revision. Documentation: https://docs.guidelab.co/api-reference/orders/requestSurgicalReportChanges ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `reviewId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `commandId` (string) **(required)**: [uuid] - `notes` (string) **(required)**: ## Responses ### 200: Changes requested - `success` (boolean) **(required)**: - `replayed` (boolean) **(required)**: ### 401: Unauthorized ### 403: Only clinic members can request changes ### 404: Order or review not found ### 409: Review or command conflict ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/surgical-report/{reviewId}/request-changes" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "commandId": "string", "notes": "string" }' ``` --- # Get current CAD design review state `GET https://api.guidelab.co/orders/{id}/cad-approval` Returns the immutable revisions and review timeline for the active CAD design hold. Documentation: https://docs.guidelab.co/api-reference/orders/getCurrentCadApproval ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Current CAD design state - `blockedByOtherHold` (boolean) **(required)**: - `review` (object,null) **(required)**: - `reviewId` (string) **(required)**: - `holdId` (string) **(required)**: - `orderPhaseId` (string) **(required)**: - `orderPhaseTaskId` (string) **(required)**: - `status` (string) **(required)**: Values: `pending_review`, `changes_requested`, `approved` - `currentRevisionNumber` (integer) **(required)**: - `reviewNotes` (string,null) **(required)**: - `bookingUrl` (string,null) **(required)**: - `reviewedAt` (string,null) **(required)**: - `currentRevision` (object) **(required)**: - `id` (string) **(required)**: - `revisionNumber` (integer) **(required)**: - `projectUrl` (string,null) **(required)**: - `submittedByMemberId` (string) **(required)**: - `submittedAt` (string) **(required)**: - `files` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `type` (string) **(required)**: - `category` (string) **(required)**: Values: `report`, `extra` - `sortOrder` (integer) **(required)**: - `revisions` (object[]) **(required)**: - `id` (string) **(required)**: - `revisionNumber` (integer) **(required)**: - `projectUrl` (string,null) **(required)**: - `submittedByMemberId` (string) **(required)**: - `submittedAt` (string) **(required)**: - `files` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `type` (string) **(required)**: - `category` (string) **(required)**: Values: `report`, `extra` - `sortOrder` (integer) **(required)**: - `events` (object[]) **(required)**: - `id` (string) **(required)**: - `sequence` (integer) **(required)**: - `eventType` (string) **(required)**: Values: `submitted`, `resubmitted`, `changes_requested`, `approved` - `revisionId` (string) **(required)**: - `actorMemberId` (string) **(required)**: - `notes` (string,null) **(required)**: - `createdAt` (string) **(required)**: ### 401: Unauthorized ### 404: Order not found ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/cad-approval" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Approve CAD design (clinic only) `POST https://api.guidelab.co/orders/{id}/cad-approval/{reviewId}/approve` Approves the current immutable revision, completes the approval task, resolves its hold, and resumes production. Documentation: https://docs.guidelab.co/api-reference/orders/approveCadApproval ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `reviewId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `commandId` (string) **(required)**: [uuid] ## Responses ### 200: Approval result - `success` (boolean) **(required)**: - `autoResumed` (boolean) **(required)**: - `replayed` (boolean) **(required)**: ### 401: Unauthorized ### 403: Only clinic members can approve reviews ### 404: Order or review not found ### 409: Review or command conflict ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/cad-approval/{reviewId}/approve" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "commandId": "string" }' ``` --- # Request a new CAD design revision (clinic only) `POST https://api.guidelab.co/orders/{id}/cad-approval/{reviewId}/request-changes` Keeps the approval task and hold open while requiring the lab to submit a new immutable revision. Documentation: https://docs.guidelab.co/api-reference/orders/requestCadApprovalChanges ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `reviewId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `commandId` (string) **(required)**: [uuid] - `notes` (string) **(required)**: ## Responses ### 200: Changes requested - `success` (boolean) **(required)**: - `replayed` (boolean) **(required)**: ### 401: Unauthorized ### 403: Only clinic members can request changes ### 404: Order or review not found ### 409: Review or command conflict ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/cad-approval/{reviewId}/request-changes" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "commandId": "string", "notes": "string" }' ``` --- # Get order files `GET https://api.guidelab.co/orders/{id}/files` Returns all files attached to an order along with product file requirements. Requirements define what file types each product expects (scans, photos, prescriptions, etc.) and their upload rules. Documentation: https://docs.guidelab.co/api-reference/orders/getOrderFiles ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Responses ### 200: List of order files and product file requirements - `files` (object[]) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `name` (string) **(required)**: - `type` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (number) **(required)**: - `url` (string) **(required)**: - `thumbnailUrl` (string,null) **(required)**: - `fileRequirementId` (string,null) **(required)**: - `orderPhaseId` (string,null) **(required)**: - `uploadedBy` (string,null) **(required)**: - `uploaderName` (string,null) **(required)**: - `uploadedByOrganizationId` (string) **(required)**: - `task` (object,null) **(required)**: - `name` (string) **(required)**: - `roomName` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `requirements` (array) **(required)**: ### 400: Order ID is required ### 401: Unauthorized ### 404: Order not found or not accessible by the current organization ### 500: Submitted order catalog revision is invalid ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/files" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List order delivery notes (DDT) `GET https://api.guidelab.co/orders/{id}/delivery-notes` Returns the DDTs issued for an order, newest first, plus which issuer a new one would use: Fatture in Cloud when it is connected with the delivery-note scope, otherwise the platform. Documentation: https://docs.guidelab.co/api-reference/orders/listOrderDeliveryNotes ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Responses ### 200: Delivery notes and issuer availability - `availability` (object) **(required)**: - `provider` (string) **(required)**: Values: `platform`, `fatture_in_cloud` - `fattureInCloudNeedsReconnect` (boolean) **(required)**: - `deliveryNotes` (object[]) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `provider` (string) **(required)**: Values: `platform`, `fatture_in_cloud` - `status` (string) **(required)**: Values: `pending`, `issued`, `failed`, `needs_review` - `number` (string,null) **(required)**: - `issueDate` (string) **(required)**: - `providerPdfUrl` (string,null) **(required)**: - `snapshot` (object) **(required)**: - `version` (number) **(required)**: Values: `1` - `capturedAt` (string) **(required)**: - `orderNumber` (string) **(required)**: - `issuer` (object) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `companyNumber` (string,null) **(required)**: - `taxRegistrationNumber` (string,null) **(required)**: - `address` (string,null) **(required)**: - `addressLine2` (string,null) **(required)**: - `city` (string,null) **(required)**: - `state` (string,null) **(required)**: - `postcode` (string,null) **(required)**: - `country` (string,null) **(required)**: - `phone` (string,null) **(required)**: - `email` (string,null) **(required)**: - `eInvoiceCode` (string,null): - `certifiedEmail` (string,null): - `customer` (object) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `companyNumber` (string,null) **(required)**: - `taxRegistrationNumber` (string,null) **(required)**: - `address` (string,null) **(required)**: - `addressLine2` (string,null) **(required)**: - `city` (string,null) **(required)**: - `state` (string,null) **(required)**: - `postcode` (string,null) **(required)**: - `country` (string,null) **(required)**: - `phone` (string,null) **(required)**: - `email` (string,null) **(required)**: - `eInvoiceCode` (string,null): - `certifiedEmail` (string,null): - `destination` (object) **(required)**: - `name` (string,null) **(required)**: - `address` (string,null) **(required)**: - `addressLine2` (string,null) **(required)**: - `city` (string,null) **(required)**: - `state` (string,null) **(required)**: - `postcode` (string,null) **(required)**: - `country` (string,null) **(required)**: - `items` (object[]) **(required)**: - `orderItemId` (string) **(required)**: - `description` (string) **(required)**: - `quantity` (number) **(required)**: - `unitPrice` (string,null) **(required)**: - `taxRate` (string,null): - `transport` (object) **(required)**: - `causale` (string) **(required)**: - `mezzo` (string) **(required)**: Values: `mittente`, `destinatario`, `vettore` - `vettore` (string,null) **(required)**: - `colli` (number) **(required)**: - `pesoKg` (string,null) **(required)**: - `aspettoBeni` (string,null) **(required)**: - `porto` (string) **(required)**: Values: `franco`, `assegnato` - `startAt` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `taxMode` (string): Values: `none`, `exclusive`, `inclusive` - `createdAt` (string) **(required)**: ### 401: Unauthorized ### 404: Order not found ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/delivery-notes" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Issue a delivery note (DDT) for an order `POST https://api.guidelab.co/orders/{id}/delivery-notes` Freezes the parties, destination, items and transport details into a DDT. Issued in Fatture in Cloud when the lab's grant carries the delivery-note scope (the provider assigns the number asynchronously), otherwise numbered and issued by the platform immediately. Documentation: https://docs.guidelab.co/api-reference/orders/createOrderDeliveryNote ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Request Body Content-Type: `application/json` - `transport` (object) **(required)**: - `causale` (string) **(required)**: - `mezzo` (string) **(required)**: Values: `mittente`, `destinatario`, `vettore` - `vettore` (string,null): - `colli` (integer) **(required)**: - `pesoKg` (string,null): - `aspettoBeni` (string,null): - `porto` (string) **(required)**: Values: `franco`, `assegnato` - `startAt` (string,null): - `notes` (string,null): - `issueDate` (string) **(required)**: - `provider` (string): Values: `platform` ## Responses ### 201: The issued (or pending provider) delivery note - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `provider` (string) **(required)**: Values: `platform`, `fatture_in_cloud` - `status` (string) **(required)**: Values: `pending`, `issued`, `failed`, `needs_review` - `number` (string,null) **(required)**: - `issueDate` (string) **(required)**: - `providerPdfUrl` (string,null) **(required)**: - `snapshot` (object) **(required)**: - `version` (number) **(required)**: Values: `1` - `capturedAt` (string) **(required)**: - `orderNumber` (string) **(required)**: - `issuer` (object) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `companyNumber` (string,null) **(required)**: - `taxRegistrationNumber` (string,null) **(required)**: - `address` (string,null) **(required)**: - `addressLine2` (string,null) **(required)**: - `city` (string,null) **(required)**: - `state` (string,null) **(required)**: - `postcode` (string,null) **(required)**: - `country` (string,null) **(required)**: - `phone` (string,null) **(required)**: - `email` (string,null) **(required)**: - `eInvoiceCode` (string,null): - `certifiedEmail` (string,null): - `customer` (object) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `companyNumber` (string,null) **(required)**: - `taxRegistrationNumber` (string,null) **(required)**: - `address` (string,null) **(required)**: - `addressLine2` (string,null) **(required)**: - `city` (string,null) **(required)**: - `state` (string,null) **(required)**: - `postcode` (string,null) **(required)**: - `country` (string,null) **(required)**: - `phone` (string,null) **(required)**: - `email` (string,null) **(required)**: - `eInvoiceCode` (string,null): - `certifiedEmail` (string,null): - `destination` (object) **(required)**: - `name` (string,null) **(required)**: - `address` (string,null) **(required)**: - `addressLine2` (string,null) **(required)**: - `city` (string,null) **(required)**: - `state` (string,null) **(required)**: - `postcode` (string,null) **(required)**: - `country` (string,null) **(required)**: - `items` (object[]) **(required)**: - `orderItemId` (string) **(required)**: - `description` (string) **(required)**: - `quantity` (number) **(required)**: - `unitPrice` (string,null) **(required)**: - `taxRate` (string,null): - `transport` (object) **(required)**: - `causale` (string) **(required)**: - `mezzo` (string) **(required)**: Values: `mittente`, `destinatario`, `vettore` - `vettore` (string,null) **(required)**: - `colli` (number) **(required)**: - `pesoKg` (string,null) **(required)**: - `aspettoBeni` (string,null) **(required)**: - `porto` (string) **(required)**: Values: `franco`, `assegnato` - `startAt` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `taxMode` (string): Values: `none`, `exclusive`, `inclusive` - `createdAt` (string) **(required)**: ### 400: Request body failed validation ### 401: Unauthorized ### 404: Order not found ### 409: Order is a draft or cancelled, or a provider DDT is already in flight ### 429: Delivery note issuance budget exhausted ### 502: Fatture in Cloud hand-off failed ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/delivery-notes" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "transport": { "causale": "string", "mezzo": "mittente", "colli": 0, "porto": "franco" }, "issueDate": "string", "provider": "platform" }' ``` --- # Get order components `GET https://api.guidelab.co/orders/{id}/components` Returns all components (e.g., implant components, materials with lot numbers) attached to an order. Accessible by both labs and clinics that have access to the order. Documentation: https://docs.guidelab.co/api-reference/orders/getOrderComponents ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Responses ### 200: List of order components with lot numbers and catalog references - `components` (object[]) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `labComponentId` (string,null) **(required)**: - `itemName` (string) **(required)**: - `lotNumber` (string) **(required)**: - `notes` (string,null) **(required)**: - `addedBy` (string) **(required)**: - `addedByName` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Order ID is required ### 401: Unauthorized ### 403: Access denied - organization does not have access to this order ### 404: Order not found ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/components" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Add component to order `POST https://api.guidelab.co/orders/{id}/components` Adds a component to an order with item name, lot number, and optional reference to the lab's component catalog. Only labs can add components to their orders. Documentation: https://docs.guidelab.co/api-reference/orders/addOrderComponent ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Request Body Content-Type: `application/json` - `lotNumber` (string) **(required)**: - `itemName` (string) **(required)**: - `labComponentId` (string): - `notes` (string): ## Responses ### 201: Created component record with user details - `component` (object) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `labComponentId` (string,null) **(required)**: - `itemName` (string) **(required)**: - `lotNumber` (string) **(required)**: - `notes` (string,null) **(required)**: - `addedBy` (string) **(required)**: - `addedByName` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 401: Unauthorized ### 403: Only labs can add components to orders ### 404: Order or catalog component not found ### 409: Order is closed, unavailable, or payment-fenced ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/components" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "lotNumber": "string", "itemName": "string", "labComponentId": "string", "notes": "string" }' ``` --- # Remove component from order `DELETE https://api.guidelab.co/orders/{id}/components` Removes a component from an order. Only labs can remove components from their orders. The component ID is passed as a query parameter. Documentation: https://docs.guidelab.co/api-reference/orders/removeOrderComponent ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID - `componentId` (string) **(required)** (in: query): Component ID to remove ## Responses ### 200: Confirmation that the component was removed - `message` (string) **(required)**: ### 400: Order ID and component ID are required ### 401: Unauthorized ### 403: Only labs can remove components from orders ### 404: Order or component not found ### 409: Order is closed, unavailable, or payment-fenced ## Example ```bash curl -X DELETE "https://api.guidelab.co/orders/{id}/components" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # The statement that accompanies a completed order's devices `GET https://api.guidelab.co/orders/{id}/conformity-statement` The latest revision of the order's statement for custom-made devices (or its national variant), for the lab or the order's clinic, also after the partnership has ended. `stale` is true when the order changed after that revision was issued. Documentation: https://docs.guidelab.co/api-reference/orders/getOrderConformityStatement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Responses ### 200: The statement - `documentId` (string) **(required)**: - `typeKey` (string) **(required)**: Values: `annex_xiii_statement`, `materials_disclosure` - `title` (string) **(required)**: - `revision` (object) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `content` (object) **(required)**: - `version` (number) **(required)**: Values: `1` - `doc` (object) **(required)**: - `stale` (boolean) **(required)**: ### 404: Order not found, or no statement issued yet - `error` (string) **(required)**: ### 409: The order is not completed - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/conformity-statement" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Issue the statement of a completed order, or get the issued one `POST https://api.guidelab.co/orders/{id}/conformity-statement` Idempotent for the lab and the order's clinic: an issued statement is returned unchanged. Its variant and language follow the clinic's country, state and postcode. Only lab managers may choose another statement type or language, or regenerate the statement from the lab's template and the order as it is now. Documentation: https://docs.guidelab.co/api-reference/orders/issueOrderConformityStatement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Request Body Content-Type: `application/json` - `typeKey` (string): Values: `annex_xiii_statement`, `materials_disclosure` - `language` (string): Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `regenerate` (boolean): (default: `false`) ## Responses ### 200: The statement already issued - `documentId` (string) **(required)**: - `typeKey` (string) **(required)**: Values: `annex_xiii_statement`, `materials_disclosure` - `title` (string) **(required)**: - `revision` (object) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `content` (object) **(required)**: - `version` (number) **(required)**: Values: `1` - `doc` (object) **(required)**: - `stale` (boolean) **(required)**: ### 201: The statement issued by this request - `documentId` (string) **(required)**: - `typeKey` (string) **(required)**: Values: `annex_xiii_statement`, `materials_disclosure` - `title` (string) **(required)**: - `revision` (object) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `content` (object) **(required)**: - `version` (number) **(required)**: Values: `1` - `doc` (object) **(required)**: - `stale` (boolean) **(required)**: ### 403: Only lab managers choose the type or language, or regenerate - `error` (string) **(required)**: ### 404: Order not found - `error` (string) **(required)**: ### 409: The order is not completed - `error` (string) **(required)**: ### 413: The order makes the statement larger than allowed - `error` (string) **(required)**: ### 422: No statement template for the order's destination - `error` (string) **(required)**: ### 429: Too many statements issued today - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/conformity-statement" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "typeKey": "annex_xiii_statement", "language": "en", "regenerate": true }' ``` --- # Add line item to an existing order `POST https://api.guidelab.co/orders/{id}/items` Adds a new line item to a draft order. Pricing is resolved from the lab's authoritative price-list publication and catalog at insertion time. Documentation: https://docs.guidelab.co/api-reference/orders/addOrderItem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Request Body Content-Type: `application/json` - `productId` (string) **(required)**: Product ID to add as a line item (example: `550e8400-e29b-41d4-a716-446655440000`) - `quantity` (integer): (default: `1`) (example: `1`) - `toothGroups` (object[]): - `id` (string) **(required)**: - `type` (string) **(required)**: Values: `single`, `bridge` - `teeth` (object[]) **(required)**: - `fdi` (integer) **(required)**: - `role` (string) **(required)**: Values: `crown`, `pontic` - `support` (string): Values: `natural`, `implant` - `implantSystemId` (string): - `implantPlatform` (string): - `materialId` (string): - `material` (string): - `shadeSystemId` (string): - `shadeOcclusal` (string): - `shadeMiddle` (string): - `shadeGingival` (string): - `shadeNotes` (string): - `defaultImplantSystemId` (string): - `defaultImplantPlatform` (string): - `notes` (string): - `customFieldValues` (object): - `value` (object): - `fileIds` (string[]): ## Responses ### 201: Created order item - `item` (object): ### 400: Validation failed ### 401: Unauthorized ### 403: Only labs can add items, or order is in a closed state ### 404: Order or product not found ### 409: Canonical product revision unavailable ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/items" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "productId": "550e8400-e29b-41d4-a716-446655440000" }' ``` --- # Update a line item on an existing order `PATCH https://api.guidelab.co/orders/{id}/items/{itemId}` Updates the configuration of an existing draft line item and re-resolves authoritative pricing. Price-affecting fields are frozen after submission. Documentation: https://docs.guidelab.co/api-reference/orders/updateOrderItem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID - `itemId` (string) **(required)** (in: path): Order item ID ## Request Body Content-Type: `application/json` - `quantity` (integer): - `toothGroups` (object[]): - `id` (string) **(required)**: - `type` (string) **(required)**: Values: `single`, `bridge` - `teeth` (object[]) **(required)**: - `fdi` (integer) **(required)**: - `role` (string) **(required)**: Values: `crown`, `pontic` - `support` (string): Values: `natural`, `implant` - `implantSystemId` (string): - `implantPlatform` (string): - `materialId` (string): - `material` (string): - `shadeSystemId` (string): - `shadeOcclusal` (string): - `shadeMiddle` (string): - `shadeGingival` (string): - `shadeNotes` (string): - `defaultImplantSystemId` (string): - `defaultImplantPlatform` (string): - `notes` (string): - `customFieldValues` (object): - `value` (object): - `fileIds` (string[]): ## Responses ### 200: Updated order item - `item` (object): ### 400: Validation failed ### 401: Unauthorized ### 403: Only labs can edit items, or order is in a closed state ### 404: Order or item not found ### 409: Canonical product revision unavailable ## Example ```bash curl -X PATCH "https://api.guidelab.co/orders/{id}/items/{itemId}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Remove a line item from an existing order `DELETE https://api.guidelab.co/orders/{id}/items/{itemId}` Removes a line item from a draft order. Order items are frozen after submission. Documentation: https://docs.guidelab.co/api-reference/orders/deleteOrderItem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID - `itemId` (string) **(required)** (in: path): Order item ID ## Responses ### 200: Item removed - `success` (boolean) **(required)**: ### 401: Unauthorized ### 403: Only labs can remove items, or order is in a closed state ### 404: Order or item not found ### 409: Bundle members must be removed as a whole bundle ## Example ```bash curl -X DELETE "https://api.guidelab.co/orders/{id}/items/{itemId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get order messages `GET https://api.guidelab.co/orders/{id}/messages` Returns messages for an order, filterable by type (all, notes, replies). Internal messages are visible only to the organization that authored them. Results are ordered by newest first. Documentation: https://docs.guidelab.co/api-reference/orders/getOrderMessages ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID - `type` (string) (in: query): Message type filter: all, notes, replies ## Responses ### 200: List of order messages with sender details Array of: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `senderUserId` (string) **(required)**: - `senderOrgId` (string) **(required)**: - `senderName` (string,null) **(required)**: - `senderOrgName` (string,null) **(required)**: - `content` (string) **(required)**: - `isInternal` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Order ID is required ### 401: Unauthorized ### 404: Order not found or not accessible by the current organization ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/messages" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get replacement order metadata `GET https://api.guidelab.co/orders/{id}/remake` Documentation: https://docs.guidelab.co/api-reference/orders/getOrderRemake ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Explicit remake link - `originalOrderId` (string) **(required)**: - `originalOrderNumber` (string) **(required)**: - `reasonId` (string) **(required)**: - `reasonName` (string) **(required)**: - `discountPercent` (number) **(required)**: - `updatedAt` (string) **(required)**: [date-time] ### 404: Order not found ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/remake" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Clear an incorrectly recorded remake link `DELETE https://api.guidelab.co/orders/{id}/remake` Documentation: https://docs.guidelab.co/api-reference/orders/clearOrderRemake ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `expectedUpdatedAt` (string,null) **(required)**: [date-time] ## Responses ### 200: Link cleared with audit history retained - `success` (boolean) **(required)**: ### 409: Link was modified concurrently ## Example ```bash curl -X DELETE "https://api.guidelab.co/orders/{id}/remake" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "expectedUpdatedAt": "string" }' ``` --- # Record or correct a remake link `PUT https://api.guidelab.co/orders/{id}/remake` Documentation: https://docs.guidelab.co/api-reference/orders/recordOrderRemake ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `originalOrderId` (string) **(required)**: - `reasonId` (string) **(required)**: - `expectedUpdatedAt` (string,null) **(required)**: [date-time] ## Responses ### 200: Remake recorded; pricing unchanged - `success` (boolean) **(required)**: ### 400: Invalid original or reason ### 409: Conflict or remake chain ## Example ```bash curl -X PUT "https://api.guidelab.co/orders/{id}/remake" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "originalOrderId": "string", "reasonId": "string", "expectedUpdatedAt": "string" }' ``` --- # Find original orders for the same client and active reasons `GET https://api.guidelab.co/orders/{id}/remake-options` Documentation: https://docs.guidelab.co/api-reference/orders/getOrderRemakeOptions ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `search` (string) (in: query): Default: `` ## Responses ### 200: At most 50 originals and 100 reasons - `orders` (object[]) **(required)**: - `id` (string) **(required)**: - `number` (string) **(required)**: - `reasons` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: ### 404: Order not found ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/remake-options" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get order print data `GET https://api.guidelab.co/orders/{id}/print-data` Returns comprehensive order data formatted for document generation and printing, including lab/clinic addresses, line items with custom fields, patient details, and document settings (title, terms, footer). Patient data is masked for labs when hidePatientFromLab is enabled. Documentation: https://docs.guidelab.co/api-reference/orders/getOrderPrintData ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Responses ### 200: Complete print-ready order data with lab, clinic, items, and document settings - `order` (object): - `lab` (object): - `clinic` (object): - `clinicLocation` (object): - `items` (array) **(required)**: - `documentSettings` (object): ### 400: Order ID is required ### 401: Unauthorized ### 404: Order not found or not accessible by the current organization ### 500: Submitted order catalog revision is invalid ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/print-data" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get subscription status `GET https://api.guidelab.co/orders/{id}/subscribe` Checks whether the authenticated user is subscribed to notifications for a specific order. Documentation: https://docs.guidelab.co/api-reference/orders/getOrderSubscription ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Responses ### 200: Subscription status boolean - `subscribed` (boolean) **(required)**: ### 400: Order ID is required ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/subscribe" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Subscribe to order `POST https://api.guidelab.co/orders/{id}/subscribe` Subscribes the authenticated user to receive notifications for a specific order. The user must belong to an organization (lab or clinic) that has access to the order. Documentation: https://docs.guidelab.co/api-reference/orders/subscribeToOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Responses ### 200: Confirmation that the user is now subscribed - `subscribed` (boolean) **(required)**: ### 400: Order ID is required ### 401: Unauthorized ### 404: Order not found or not accessible by the current organization ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/subscribe" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Unsubscribe from order `DELETE https://api.guidelab.co/orders/{id}/subscribe` Unsubscribes the authenticated user from notifications for a specific order. Documentation: https://docs.guidelab.co/api-reference/orders/unsubscribeFromOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Responses ### 200: Confirmation that the user is now unsubscribed - `subscribed` (boolean) **(required)**: ### 400: Order ID is required ### 401: Unauthorized ## Example ```bash curl -X DELETE "https://api.guidelab.co/orders/{id}/subscribe" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get order tags `GET https://api.guidelab.co/orders/{id}/tags` Returns all tags applied to an order. Accessible by both labs and clinics that have access to the order. Documentation: https://docs.guidelab.co/api-reference/orders/getOrderTags ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Responses ### 200: List of tags applied to the order with tag details - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `tagId` (string) **(required)**: - `appliedBy` (string) **(required)**: - `createdAt` (string) **(required)**: - `tag` (object): ### 400: Order ID is required ### 401: Unauthorized ### 403: Access denied - organization does not have access to this order ### 404: Order not found ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/tags" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Add tag to order `POST https://api.guidelab.co/orders/{id}/tags` Applies an existing tag from the lab's tag catalog to an order. The tag must be active and belong to the order's lab. Prevents duplicate tag applications. Documentation: https://docs.guidelab.co/api-reference/orders/addOrderTag ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID ## Request Body Content-Type: `application/json` - `tagId` (string) **(required)**: ## Responses ### 201: Created tag application with full tag details - `orderTag` (object) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `tagId` (string) **(required)**: - `appliedBy` (string) **(required)**: - `createdAt` (string) **(required)**: - `tag` (object): ### 400: Invalid request body ### 401: Unauthorized ### 403: Access denied - organization does not have access to this order ### 404: Order or tag not found ### 409: Tag is already applied to this order ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/tags" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "tagId": "string" }' ``` --- # Remove tag from order `DELETE https://api.guidelab.co/orders/{id}/tags` Removes a tag from an order. The tag ID is passed as a query parameter. Accessible by both labs and clinics with access to the order. Documentation: https://docs.guidelab.co/api-reference/orders/removeOrderTag ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Order ID - `tagId` (string) **(required)** (in: query): Tag ID to remove ## Responses ### 200: Confirmation that the tag was removed from the order - `message` (string) **(required)**: ### 400: Order ID and tag ID are required ### 401: Unauthorized ### 403: Access denied - organization does not have access to this order ### 404: Order not found or tag not applied to this order ## Example ```bash curl -X DELETE "https://api.guidelab.co/orders/{id}/tags" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Quote the shipping options for an order `GET https://api.guidelab.co/orders/{id}/shipping-options` Prices each shipping type the lab offers for this order's destination and weight, exactly as submission will freeze it, with the open orders it may ship together with. For a draft, the organization that owns it may ask; for a submitted order, only the lab while it can still change the order's shipping. Missing product weights and an uncovered destination are reported to the lab only. Documentation: https://docs.guidelab.co/api-reference/orders/getOrderShippingOptions ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: The priced shipping options - `needsShipping` (boolean) **(required)**: - `options` (object[]) **(required)**: - `shippingTypeId` (string) **(required)**: - `name` (string) **(required)**: - `method` (string) **(required)**: Values: `carrier`, `local_driver`, `collection` - `amount` (string) **(required)**: - `insuranceAmount` (string,null) **(required)**: - `combine` (object[]) **(required)**: - `anchorOrderId` (string) **(required)**: - `orderNumbers` (string[]) **(required)**: - `dueDate` (string,null) **(required)**: - `amount` (string) **(required)**: - `warnings` (object): - `uncoveredDestination` (boolean) **(required)**: - `weightGrams` (integer) **(required)**: - `missingWeightProducts` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: ### 401: Unauthorized ### 404: Order not found ### 409: The order cannot be quoted yet (shipping_quote_unavailable) or its shipping can no longer change (shipping_not_editable) ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/shipping-options" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Change a submitted order's shipping `PUT https://api.guidelab.co/orders/{id}/shipping` Lab only. Sets the shipping type, insurance and combined shipment of an open order that is not yet paid or invoiced, re-pricing only this order from the current rate table. A null shipping type removes the charge. Orders that others have joined keep their shipping type. Documentation: https://docs.guidelab.co/api-reference/orders/updateOrderShipping ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `shippingTypeId` (string,null) **(required)**: - `shippingInsured` (boolean) **(required)**: - `shipWithOrderId` (string,null) **(required)**: ## Responses ### 200: The order's shipping after the change - `shipping` (object,null) **(required)**: - `shippingTypeId` (string,null) **(required)**: - `name` (string) **(required)**: - `method` (string,null) **(required)**: Values: `carrier`, `local_driver`, `collection`, `null` - `amount` (string) **(required)**: - `insuranceAmount` (string) **(required)**: - `totalAmount` (string) **(required)**: - `group` (object,null) **(required)**: - `anchorOrderId` (string) **(required)**: - `orders` (object[]) **(required)**: - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `status` (string) **(required)**: Values: `draft`, `submitted`, `active`, `completed`, `cancelled`, `on_hold` - `shippingLab` (object) **(required)**: - `weightGrams` (integer,null) **(required)**: - `missingWeightCount` (integer) **(required)**: - `zoneName` (string,null) **(required)**: - `notCharged` (boolean) **(required)**: - `editable` (boolean) **(required)**: ### 401: Unauthorized ### 403: Only the lab changes an order's shipping ### 404: Order not found ### 409: shipping_not_editable, shipping_group_has_members or shipping_unavailable ## Example ```bash curl -X PUT "https://api.guidelab.co/orders/{id}/shipping" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "shippingTypeId": "string", "shippingInsured": true, "shipWithOrderId": "string" }' ``` --- # What a new shipment for an order can carry `GET https://api.guidelab.co/orders/{id}/shipment-candidates` Lab only. The order's shipping group, or the order alone, with each physical line's quantity not yet on a live shipment, the shipping method the clinic chose and the default destination. Documentation: https://docs.guidelab.co/api-reference/orders/getOrderShipmentCandidates ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: The shippable orders and lines - `partnershipId` (string) **(required)**: - `partnershipActive` (boolean) **(required)**: - `method` (string,null) **(required)**: Values: `carrier`, `local_driver`, `collection`, `null` - `clinicLocationId` (string,null) **(required)**: - `clinicAddress` (object) **(required)**: - `name` (string) **(required)**: - `addressLine1` (string,null) **(required)**: - `addressLine2` (string,null) **(required)**: - `city` (string,null) **(required)**: - `region` (string,null) **(required)**: - `postcode` (string,null) **(required)**: - `country` (string,null) **(required)**: - `contactPhone` (string,null) **(required)**: - `orders` (object[]) **(required)**: - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `status` (string) **(required)**: Values: `draft`, `submitted`, `active`, `completed`, `cancelled`, `on_hold` - `shippable` (boolean) **(required)**: - `items` (object[]) **(required)**: - `id` (string) **(required)**: - `productName` (string,null) **(required)**: - `quantity` (integer) **(required)**: - `remainingQuantity` (integer) **(required)**: - `truncated` (boolean) **(required)**: ### 401: Unauthorized ### 403: Only the lab ships orders ### 404: Order not found ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/shipment-candidates" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get an order's revision-aware QC state `GET https://api.guidelab.co/orders/{id}/qc` Documentation: https://docs.guidelab.co/api-reference/quality-control/getOrderQc ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `historyLimit` (integer) (in: query): Default: `10` ## Responses ### 200: QC configuration, current gate state, and bounded history - `qcEnabled` (boolean) **(required)**: - `selectAllEnabled` (boolean) **(required)**: - `fulfillmentRevision` (integer) **(required)**: - `gatePassed` (boolean) **(required)**: - `checklist` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `sortOrder` (integer) **(required)**: - `latestInspection` (object,null) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderRevision` (integer) **(required)**: - `attemptNumber` (integer) **(required)**: - `outcome` (string) **(required)**: Values: `passed`, `failed` - `notes` (string,null) **(required)**: - `completedByUserId` (string,null) **(required)**: - `completedByName` (string,null) **(required)**: - `completedAt` (string) **(required)**: - `results` (object[]) **(required)**: - `checklistItemId` (string) **(required)**: - `itemName` (string) **(required)**: - `passed` (boolean) **(required)**: - `notes` (string,null) **(required)**: - `history` (object[]) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderRevision` (integer) **(required)**: - `attemptNumber` (integer) **(required)**: - `outcome` (string) **(required)**: Values: `passed`, `failed` - `notes` (string,null) **(required)**: - `completedByUserId` (string,null) **(required)**: - `completedByName` (string,null) **(required)**: - `completedAt` (string) **(required)**: - `results` (object[]) **(required)**: - `checklistItemId` (string) **(required)**: - `itemName` (string) **(required)**: - `passed` (boolean) **(required)**: - `notes` (string,null) **(required)**: ### 401: Unauthorized ### 403: Lab access required ### 404: Order not found ### 409: QC checklist exceeds its bounded execution limit ## Example ```bash curl -X GET "https://api.guidelab.co/orders/{id}/qc" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Record an immutable QC inspection `POST https://api.guidelab.co/orders/{id}/qc` Documentation: https://docs.guidelab.co/api-reference/quality-control/completeOrderQc ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `results` (object[]) **(required)**: - `checklistItemId` (string) **(required)**: - `passed` (boolean) **(required)**: - `notes` (string,null): - `notes` (string,null): ## Responses ### 201: QC inspection recorded - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderRevision` (integer) **(required)**: - `attemptNumber` (integer) **(required)**: - `outcome` (string) **(required)**: Values: `passed`, `failed` - `notes` (string,null) **(required)**: - `completedByUserId` (string,null) **(required)**: - `completedByName` (string,null) **(required)**: - `completedAt` (string) **(required)**: - `results` (object[]) **(required)**: - `checklistItemId` (string) **(required)**: - `itemName` (string) **(required)**: - `passed` (boolean) **(required)**: - `notes` (string,null) **(required)**: ### 400: Checklist result set is incomplete or invalid ### 401: Unauthorized ### 403: Lab access required ### 404: Order not found ### 409: QC is disabled or order is not active ## Example ```bash curl -X POST "https://api.guidelab.co/orders/{id}/qc" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "results": [ { "checklistItemId": "string", "passed": true, "notes": "string" } ], "notes": "string" }' ``` --- # List outbound shipments visible to the active organization `GET https://api.guidelab.co/shipments` Documentation: https://docs.guidelab.co/api-reference/shipments/listShipments ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `status` (string) (in: query): Values: `draft`, `packing`, `ready`, `in_transit`, `delivery_exception`, `delivered`, `returned`, `cancelled` - `partnershipId` (string) (in: query): - `orderId` (string) (in: query): - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `25` ## Responses ### 200: Paginated shipments - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `clinicId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `shipmentNumber` (integer) **(required)**: - `method` (string) **(required)**: Values: `carrier`, `local_driver` - `status` (string) **(required)**: Values: `draft`, `packing`, `ready`, `in_transit`, `delivery_exception`, `delivered`, `returned`, `cancelled` - `version` (integer) **(required)**: - `destinationSource` (string) **(required)**: Values: `one_off`, `clinic_location` - `destinationLocationId` (string,null) **(required)**: - `destinationName` (string) **(required)**: - `city` (string) **(required)**: - `region` (string,null) **(required)**: - `postcode` (string) **(required)**: - `country` (string) **(required)**: - `scheduledDate` (string,null) **(required)**: - `dispatchedAt` (string,null) **(required)**: - `deliveredAt` (string,null) **(required)**: - `returnedAt` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `pagination` (object) **(required)**: - `page` (integer) **(required)**: - `limit` (integer) **(required)**: - `total` (integer) **(required)**: - `totalPages` (integer) **(required)**: ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/shipments" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a quantity-level outbound shipment `POST https://api.guidelab.co/shipments` Documentation: https://docs.guidelab.co/api-reference/shipments/createShipment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `commandId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `method` (string) **(required)**: Values: `carrier`, `local_driver` - `destination` (object): - `name` (string) **(required)**: - `addressLine1` (string) **(required)**: - `addressLine2` (string): - `city` (string) **(required)**: - `region` (string): - `postcode` (string) **(required)**: - `country` (string) **(required)**: - `contactName` (string): - `contactPhone` (string): - `destinationLocationId` (string): - `driverName` (string): - `driverPhone` (string): - `scheduledDate` (string): - `notes` (string): - `items` (object[]) **(required)**: - `clientReference` (string) **(required)**: - `orderItemId` (string) **(required)**: - `quantity` (integer) **(required)**: - `kind` (string): (default: `fulfillment`) Values: `fulfillment`, `replacement` - `replacementForShipmentItemId` (string): - `notes` (string): - `packages` (object[]): - `clientReference` (string) **(required)**: - `weightGrams` (integer): - `lengthMm` (integer): - `widthMm` (integer): - `heightMm` (integer): - `items` (object[]) **(required)**: - `allocationReference` (string) **(required)**: - `quantity` (integer) **(required)**: ## Responses ### 201: Shipment created ### 400: Invalid shipment allocation ### 401: Unauthorized ### 403: Lab access required ### 409: Command identity or allocation conflict ## Example ```bash curl -X POST "https://api.guidelab.co/shipments" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "commandId": "string", "partnershipId": "string", "method": "carrier", "items": [ { "clientReference": "string", "orderItemId": "string", "quantity": 0, "kind": "fulfillment", "replacementForShipmentItemId": "string", "notes": "string" } ] }' ``` --- # Transition an outbound shipment `POST https://api.guidelab.co/shipments/{id}/transition` Documentation: https://docs.guidelab.co/api-reference/shipments/transitionShipment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `commandId` (string) **(required)**: - `toStatus` (string) **(required)**: Values: `draft`, `packing`, `ready`, `in_transit`, `delivery_exception`, `delivered`, `returned`, `cancelled` - `expectedVersion` (integer) **(required)**: - `occurredAt` (string): - `details` (object): - `deliveryProof` (object): - `recipientName` (string) **(required)**: - `proofType` (string) **(required)**: Values: `signature`, `photo`, `manual` - `fileId` (string): ## Responses ### 200: Shipment transitioned ### 400: Invalid transition ### 404: Shipment not found ### 409: Stale version or command identity conflict ## Example ```bash curl -X POST "https://api.guidelab.co/shipments/{id}/transition" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "commandId": "string", "toStatus": "draft", "expectedVersion": 0, "occurredAt": "string", "details": {}, "deliveryProof": { "recipientName": "string", "proofType": "signature", "fileId": "string" } }' ``` --- # Attach a manually purchased carrier label `POST https://api.guidelab.co/shipments/{id}/labels/manual` Documentation: https://docs.guidelab.co/api-reference/shipments/createManualShipmentLabel ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `commandId` (string) **(required)**: - `expectedVersion` (integer) **(required)**: - `packageId` (string) **(required)**: - `carrier` (string) **(required)**: - `serviceCode` (string): - `trackingNumber` (string) **(required)**: - `trackingUrl` (string): [uri] - `cost` (string): - `currency` (string) **(required)**: Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` ## Responses ### 200: Manual label attached ### 404: Shipment or package not found ### 409: Stale shipment or command identity conflict ## Example ```bash curl -X POST "https://api.guidelab.co/shipments/{id}/labels/manual" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "commandId": "string", "expectedVersion": 0, "packageId": "string", "carrier": "string", "trackingNumber": "string", "currency": "GBP" }' ``` --- # Void an attached manual carrier label `POST https://api.guidelab.co/shipments/{id}/labels/{labelId}/void` Documentation: https://docs.guidelab.co/api-reference/shipments/voidShipmentLabel ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `labelId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `commandId` (string) **(required)**: - `expectedVersion` (integer) **(required)**: - `reason` (string): ## Responses ### 200: Label voided ### 404: Shipment or label not found ### 409: Stale shipment or provider void required ## Example ```bash curl -X POST "https://api.guidelab.co/shipments/{id}/labels/{labelId}/void" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "commandId": "string", "expectedVersion": 0, "reason": "string" }' ``` --- # Record a replay-safe package pack/unpack scan `POST https://api.guidelab.co/shipments/{id}/scans` Documentation: https://docs.guidelab.co/api-reference/shipments/recordShipmentScan ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `commandId` (string) **(required)**: - `expectedVersion` (integer) **(required)**: - `packageId` (string) **(required)**: - `shipmentItemId` (string) **(required)**: - `action` (string) **(required)**: Values: `pack`, `unpack` - `quantity` (integer) **(required)**: - `barcode` (string): ## Responses ### 200: Scan recorded ### 400: Scan violates the package allocation ### 404: Shipment or package allocation not found ### 409: Stale shipment or command identity conflict ## Example ```bash curl -X POST "https://api.guidelab.co/shipments/{id}/scans" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "commandId": "string", "expectedVersion": 0, "packageId": "string", "shipmentItemId": "string", "action": "pack", "quantity": 0 }' ``` --- # Get an outbound shipment `GET https://api.guidelab.co/shipments/{id}` Documentation: https://docs.guidelab.co/api-reference/shipments/getShipment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Shipment detail - `shipment` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `clinicId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `shipmentNumber` (integer) **(required)**: - `method` (string) **(required)**: Values: `carrier`, `local_driver` - `status` (string) **(required)**: Values: `draft`, `packing`, `ready`, `in_transit`, `delivery_exception`, `delivered`, `returned`, `cancelled` - `version` (integer) **(required)**: - `destinationSource` (string) **(required)**: Values: `one_off`, `clinic_location` - `destinationLocationId` (string,null) **(required)**: - `destinationName` (string) **(required)**: - `city` (string) **(required)**: - `region` (string,null) **(required)**: - `postcode` (string) **(required)**: - `country` (string) **(required)**: - `scheduledDate` (string,null) **(required)**: - `dispatchedAt` (string,null) **(required)**: - `deliveredAt` (string,null) **(required)**: - `returnedAt` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `addressLine1` (string) **(required)**: - `addressLine2` (string,null) **(required)**: - `contactName` (string,null) **(required)**: - `contactPhone` (string,null) **(required)**: - `driverName` (string,null) **(required)**: - `driverPhone` (string,null) **(required)**: - `notes` (string,null): - `items` (object[]) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderItemId` (string) **(required)**: - `quantity` (integer) **(required)**: - `kind` (string) **(required)**: Values: `fulfillment`, `replacement` - `replacementForShipmentItemId` (string,null) **(required)**: - `releasedAt` (string,null) **(required)**: - `orderNumber` (string): - `productName` (string,null): - `packages` (object[]) **(required)**: - `id` (string) **(required)**: - `packageNumber` (integer) **(required)**: - `weightGrams` (integer,null) **(required)**: - `packageItems` (object[]) **(required)**: - `id` (string) **(required)**: - `packageId` (string) **(required)**: - `shipmentItemId` (string) **(required)**: - `quantity` (integer) **(required)**: - `packedQuantity` (integer): - `labels` (object[]) **(required)**: - `id` (string) **(required)**: - `packageId` (string) **(required)**: - `carrier` (string,null) **(required)**: - `trackingNumber` (string,null) **(required)**: - `trackingUrl` (string,null) **(required)**: - `status` (string) **(required)**: - `provider` (string): - `events` (object[]) **(required)**: - `id` (string) **(required)**: - `sequence` (integer) **(required)**: - `eventType` (string) **(required)**: - `fromStatus` (string,null) **(required)**: - `toStatus` (string,null) **(required)**: - `occurredAt` (string) **(required)**: - `deliveryProof` (object,null) **(required)**: - `recipientName` (string) **(required)**: - `proofType` (string) **(required)**: - `deliveredAt` (string) **(required)**: ### 404: Shipment not found ## Example ```bash curl -X GET "https://api.guidelab.co/shipments/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Quote bounded ShipStation rates for one shipment package `POST https://api.guidelab.co/shipments/{id}/rates` Documentation: https://docs.guidelab.co/api-reference/shipments/quoteShipmentPackageRates ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `packageId` (string) **(required)**: - `carrierIds` (string[]): ## Responses ### 200: Signed, short-lived rate choices ### 400: Shipment address or package data is incomplete ### 404: Shipment package not found ### 409: Shipment or shipping integration is not eligible ### 429: Provider operation budget exhausted ### 502: Rate provider failed safely ### 503: Provider integration disabled ## Example ```bash curl -X POST "https://api.guidelab.co/shipments/{id}/rates" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "packageId": "string", "carrierIds": [ "string" ] }' ``` --- # Purchase a ShipStation label from a signed rate `POST https://api.guidelab.co/shipments/{id}/labels/provider` Documentation: https://docs.guidelab.co/api-reference/shipments/purchaseProviderShipmentLabel ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `commandId` (string) **(required)**: - `expectedVersion` (integer) **(required)**: - `rateToken` (string) **(required)**: ## Responses ### 200: Existing label command replayed ### 201: Provider label purchased and stored ### 202: Provider outcome is being recovered or finalized ### 404: Shipment package not found ### 409: Stale or conflicting shipment command ### 429: Paid provider budget exhausted ### 503: Provider integration disabled ## Example ```bash curl -X POST "https://api.guidelab.co/shipments/{id}/labels/provider" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "commandId": "string", "expectedVersion": 0, "rateToken": "string" }' ``` --- # Void a ShipStation label without repeating the provider mutation `POST https://api.guidelab.co/shipments/{id}/labels/{labelId}/provider-void` Documentation: https://docs.guidelab.co/api-reference/shipments/voidProviderShipmentLabel ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `labelId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `commandId` (string) **(required)**: - `expectedVersion` (integer) **(required)**: - `reason` (string): ## Responses ### 200: Existing void command replayed ### 201: Provider label voided ### 202: Provider outcome is being recovered or finalized ### 404: Provider label not found ### 409: Stale or conflicting shipment command ### 429: Provider mutation budget exhausted ### 503: Provider integration disabled ## Example ```bash curl -X POST "https://api.guidelab.co/shipments/{id}/labels/{labelId}/provider-void" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "commandId": "string", "expectedVersion": 0, "reason": "string" }' ``` --- # Get durable provider operation status `GET https://api.guidelab.co/shipments/{id}/provider-operations/{operationId}` Documentation: https://docs.guidelab.co/api-reference/shipments/getShipmentProviderOperation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `operationId` (string) **(required)** (in: path): ## Responses ### 200: Provider operation status ### 404: Provider operation not found ## Example ```bash curl -X GET "https://api.guidelab.co/shipments/{id}/provider-operations/{operationId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Download an authorized immutable carrier-label PDF `GET https://api.guidelab.co/shipments/{id}/labels/{labelId}/document` Documentation: https://docs.guidelab.co/api-reference/shipments/downloadShipmentLabelDocument ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `labelId` (string) **(required)** (in: path): ## Responses ### 200: Carrier-label PDF ### 404: Stored provider label not found ### 413: Stored provider label exceeds its fixed limit ### 429: Download budget exhausted ## Example ```bash curl -X GET "https://api.guidelab.co/shipments/{id}/labels/{labelId}/document" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List order tags `GET https://api.guidelab.co/order-tags` Returns a paginated list of order tags for the organization. Labs see their own tags; clinics must provide a labId to see a partner lab's tags. Documentation: https://docs.guidelab.co/api-reference/order-tags/listOrderTags ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` (string) (in: query): Include inactive tags - `search` (string) (in: query): Search term - `page` (string) (in: query): Page number - `limit` (string) (in: query): Items per page - `labId` (string) (in: query): Lab ID (required for clinic users) ## Responses ### 200: Paginated list of order tags - `data` (array) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters or missing labId for clinic ### 401: Unauthorized — valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/order-tags" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create an order tag `POST https://api.guidelab.co/order-tags` Creates a new order tag with a name, color, and optional description. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/order-tags/createOrderTag ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `color` (string): (default: `#6366f1`) - `description` (string): - `sortOrder` (integer): (default: `0`) - `isActive` (boolean): (default: `true`) ## Responses ### 201: Tag created successfully - `tag` (object): ### 400: Invalid request body ### 401: Unauthorized — valid session required ### 403: Forbidden — only lab organizations can create tags ## Example ```bash curl -X POST "https://api.guidelab.co/order-tags" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "color": "string", "description": "string", "sortOrder": 0, "isActive": true }' ``` --- # Get an order tag `GET https://api.guidelab.co/order-tags/{id}` Returns a single order tag by ID. Clinics can only view tags from their partner labs. Documentation: https://docs.guidelab.co/api-reference/order-tags/getOrderTag ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Tag ID ## Responses ### 200: Tag details - `tag` (object): ### 400: Tag ID is required ### 401: Unauthorized — valid session required ### 404: Tag not found or no partnership access ## Example ```bash curl -X GET "https://api.guidelab.co/order-tags/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Deactivate an order tag `DELETE https://api.guidelab.co/order-tags/{id}` Soft-deletes an order tag by setting it to inactive. The tag remains in the database for historical reference. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/order-tags/deleteOrderTag ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Tag ID ## Responses ### 200: Tag deactivated successfully - `tag` (object): - `message` (string) **(required)**: ### 400: Tag ID is required ### 401: Unauthorized — valid session required ### 403: Forbidden — only lab organizations can delete tags ### 404: Tag not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/order-tags/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update an order tag `PUT https://api.guidelab.co/order-tags/{id}` Updates an existing order tag's name, color, description, active status, or sort order. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/order-tags/updateOrderTag ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Tag ID ## Request Body Content-Type: `application/json` - `name` (string): - `color` (string): - `description` (string): - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 200: Tag updated successfully - `tag` (object): ### 400: Invalid request body ### 401: Unauthorized — valid session required ### 403: Forbidden — only lab organizations can update tags ### 404: Tag not found ## Example ```bash curl -X PUT "https://api.guidelab.co/order-tags/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "color": "string", "description": "string", "sortOrder": 0, "isActive": true }' ``` --- # List order filter presets `GET https://api.guidelab.co/order-filter-presets` Returns the organization's order filter presets, ordered by display position. Lab presets are persisted and editable, initialized during organization creation or by the explicit settings-defaults command. Clinics always receive the fixed built-in set. Documentation: https://docs.guidelab.co/api-reference/order-filter-presets/listOrderFilterPresets ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` (string) (in: query): Include inactive presets ## Responses ### 200: List of order filter presets - `data` (array) **(required)**: ### 401: Unauthorized — valid session required ### 409: Preset capacity exceeded ## Example ```bash curl -X GET "https://api.guidelab.co/order-filter-presets" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create an order filter preset `POST https://api.guidelab.co/order-filter-presets` Documentation: https://docs.guidelab.co/api-reference/order-filter-presets/createOrderFilterPreset ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `icon` (string,null): - `filters` (object): (default: `[object Object]`) - `statuses` (string[]): - `types` (string[]): - `doctorName` (string,null): - `patientId` (string,null): - `labId` (string,null): - `hasFiles` (boolean,null): - `hasAdvanceRequest` (boolean,null): - `upcomingDelivery` (boolean,null): - `hasUnreadMessages` (boolean,null): - `needsAction` (boolean,null): - `sort` (object): (default: `[object Object]`) - `field` (string): (default: `createdAt`) Values: `createdAt`, `dueDate`, `submittedAt`, `orderNumber`, `status` - `direction` (string): (default: `desc`) Values: `asc`, `desc` - `columns` (string[]): (default: ``) - `layout` (string): (default: `table`) Values: `table` - `isDefault` (boolean): (default: `false`) ## Responses ### 201: Preset created - `preset` (object): ### 400: Invalid request body ### 401: Unauthorized — valid session required ### 403: Forbidden - lab organization manager required ### 409: Preset capacity exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/order-filter-presets" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string" }' ``` --- # Count orders per filter preset `GET https://api.guidelab.co/order-filter-presets/counts` Returns the number of orders matching each active preset's filter, keyed by preset id. Powers the stat cards on the orders page. Clinics are counted against the fixed built-in set. Documentation: https://docs.guidelab.co/api-reference/order-filter-presets/getOrderFilterPresetCounts ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Counts keyed by preset id - `counts` (object) **(required)**: ### 401: Unauthorized — valid session required ### 409: Preset capacity exceeded ## Example ```bash curl -X GET "https://api.guidelab.co/order-filter-presets/counts" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Reorder order filter presets `POST https://api.guidelab.co/order-filter-presets/reorder` Documentation: https://docs.guidelab.co/api-reference/order-filter-presets/reorderOrderFilterPresets ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `presetIds` (string[]) **(required)**: ## Responses ### 200: Presets reordered - `success` (boolean) **(required)**: ### 400: Invalid request body ### 401: Unauthorized — valid session required ### 403: Forbidden - lab organization manager required ### 404: One or more presets not found ## Example ```bash curl -X POST "https://api.guidelab.co/order-filter-presets/reorder" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "presetIds": [ "string" ] }' ``` --- # Reset order filter presets to the defaults `POST https://api.guidelab.co/order-filter-presets/reset-defaults` Deletes every order filter preset the lab has - including presets it created or edited - and recreates the lab stock set, in stock order. Destructive and not recoverable. Documentation: https://docs.guidelab.co/api-reference/order-filter-presets/resetOrderFilterPresets ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Presets reset to the stock set - `data` (object) **(required)**: - `reset` (number) **(required)**: ### 401: Unauthorized - valid session required ### 403: Forbidden - lab organization manager required ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/order-filter-presets/reset-defaults" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete an order filter preset `DELETE https://api.guidelab.co/order-filter-presets/{id}` Documentation: https://docs.guidelab.co/api-reference/order-filter-presets/deleteOrderFilterPreset ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Filter preset ID ## Responses ### 200: Preset deleted - `success` (boolean) **(required)**: ### 401: Unauthorized — valid session required ### 403: Forbidden - lab organization manager required ### 404: Preset not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/order-filter-presets/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update an order filter preset `PUT https://api.guidelab.co/order-filter-presets/{id}` Documentation: https://docs.guidelab.co/api-reference/order-filter-presets/updateOrderFilterPreset ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Filter preset ID ## Request Body Content-Type: `application/json` - `name` (string): - `icon` (string,null): - `filters` (object): - `statuses` (string[]): - `types` (string[]): - `doctorName` (string,null): - `patientId` (string,null): - `labId` (string,null): - `hasFiles` (boolean,null): - `hasAdvanceRequest` (boolean,null): - `upcomingDelivery` (boolean,null): - `hasUnreadMessages` (boolean,null): - `needsAction` (boolean,null): - `sort` (object): - `field` (string): (default: `createdAt`) Values: `createdAt`, `dueDate`, `submittedAt`, `orderNumber`, `status` - `direction` (string): (default: `desc`) Values: `asc`, `desc` - `columns` (string[]): - `layout` (string): Values: `table` - `isDefault` (boolean): ## Responses ### 200: Preset updated - `preset` (object): ### 400: Invalid request body ### 401: Unauthorized — valid session required ### 403: Forbidden - lab organization manager required ### 404: Preset not found ## Example ```bash curl -X PUT "https://api.guidelab.co/order-filter-presets/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Search patients (autocomplete / combobox) `GET https://api.guidelab.co/patients` Search patients with fuzzy matching for autocomplete/combobox use. Labs see patients from partnered clinics (respecting share-all-patients and lab access settings). Clinics see only their own patients. Anonymized patients are masked for labs. Documentation: https://docs.guidelab.co/api-reference/patients/searchPatients ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `q` (string) (in: query): Search query for patient name, code, or external ID Default: `` - `clinicId` (string) (in: query): Filter patients by clinic ID - `limit` (integer) (in: query): Maximum number of results to return Default: `50` ## Responses ### 200: List of matching patients - `patients` (object[]) **(required)**: - `id` (string) **(required)**: - `clinicId` (string) **(required)**: - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: - `gender` (string,null) **(required)**: - `dateOfBirth` (string,null) **(required)**: - `phone` (string,null) **(required)**: - `email` (string,null) **(required)**: - `externalId` (string,null) **(required)**: - `clinicName` (string,null) **(required)**: - `patientCode` (string,null) **(required)**: - `fullName` (string) **(required)**: - `clinic` (object,null) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `isAnonymized` (boolean) **(required)**: ### 400: Invalid query parameters ### 401: Unauthorized ### 403: Access denied to clinic's patients ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/patients" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a new patient `POST https://api.guidelab.co/patients` Create a new patient record. Clinics can only create patients for themselves. Labs can create patients for partnered clinics and automatically get lab access granted. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/patients/createPatient ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `clinicId` (string) **(required)**: - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: - `gender` (string): Values: `male`, `female`, `other`, `prefer_not_to_say` - `dateOfBirth` (string,null): - `phone` (string): - `email` (object): - `externalId` (string): - `notes` (string): ## Responses ### 201: Patient created successfully - `patient` (object) **(required)**: - `id` (string) **(required)**: - `clinicId` (string) **(required)**: - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: - `fullName` (string) **(required)**: ### 400: Invalid request body ### 401: Unauthorized ### 403: Cannot create patient for this clinic ### 409: A patient with this external ID already exists for this clinic ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/patients" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "clinicId": "string", "firstName": "string", "lastName": "string" }' ``` --- # Paginated patient list `GET https://api.guidelab.co/patients/list` Retrieve a paginated list of patients with order counts. Labs see patients from partnered clinics (respecting share-all-patients and lab access settings). Clinics see only their own. Supports search, sorting, and clinic filtering. Documentation: https://docs.guidelab.co/api-reference/patients/listPatients ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Page number Default: `1` - `limit` (integer) (in: query): Items per page Default: `20` - `search` (string) (in: query): Search term for patient name or external ID - `clinicId` (string) (in: query): Filter by clinic ID - `sortBy` (string) (in: query): Field to sort by Values: `name`, `practice`, `dateOfBirth`, `orders`, `createdAt` Default: `name` - `sortOrder` (string) (in: query): Sort direction Values: `asc`, `desc` Default: `asc` ## Responses ### 200: Paginated list of patients with order counts - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: - `fullName` (string) **(required)**: - `dateOfBirth` (string,null) **(required)**: - `phone` (string,null) **(required)**: - `email` (string,null) **(required)**: - `externalId` (string,null) **(required)**: - `clinicId` (string) **(required)**: - `clinicName` (string,null) **(required)**: - `orderCount` (number) **(required)**: - `createdAt` (string) **(required)**: - `patientCode` (string,null) **(required)**: - `isAnonymized` (boolean) **(required)**: - `hiddenFromLab` (boolean) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 401: Unauthorized ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/patients/list" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get a single patient by ID `GET https://api.guidelab.co/patients/{id}` Retrieve a patient's details. Labs can access patients from partnered clinics (subject to lab access and share-all-patients settings). Anonymized patients return masked data for labs. Clinics can only access their own patients. Documentation: https://docs.guidelab.co/api-reference/patients/getPatient ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Patient ID ## Responses ### 200: Patient details (may be anonymized for labs) - `patient` (object) **(required)**: - `id` (string) **(required)**: - `clinicId` (string) **(required)**: - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: - `gender` (string,null) **(required)**: - `dateOfBirth` (string,null) **(required)**: - `phone` (string,null) **(required)**: - `email` (string,null) **(required)**: - `externalId` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `clinicName` (string,null) **(required)**: - `fullName` (string) **(required)**: - `patientCode` (string,null) **(required)**: - `isAnonymized` (boolean) **(required)**: ### 401: Unauthorized ### 403: Access denied to this patient ### 404: Patient not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/patients/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Erase a patient identity `DELETE https://api.guidelab.co/patients/{id}` Immediately pseudonymizes a clinic-owned patient and starts bounded cleanup of retained identity copies. Replays are idempotent. Documentation: https://docs.guidelab.co/api-reference/patients/erasePatientIdentity ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 202: Identity erasure accepted or already in progress - `status` (string) **(required)**: Values: `requested`, `already_requested` ### 401: Unauthorized ### 403: Clinic manager access required ### 404: Patient not found ### 409: Controller retention hold blocks identity erasure ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/patients/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a patient's details `PUT https://api.guidelab.co/patients/{id}` Update an existing patient's details. Clinics can only update their own patients. Labs can update patients from partnered clinics they have access to (subject to lab access and share-all-patients settings). Anonymized/hidden patients cannot be edited. The patient's clinic and patient code cannot be changed. Documentation: https://docs.guidelab.co/api-reference/patients/updatePatient ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Patient ID ## Request Body Content-Type: `application/json` - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: - `gender` (string): Values: `male`, `female`, `other`, `prefer_not_to_say` - `dateOfBirth` (string,null): - `phone` (string): - `email` (object): - `externalId` (string): - `notes` (string): ## Responses ### 200: Patient updated successfully - `patient` (object) **(required)**: - `id` (string) **(required)**: - `clinicId` (string) **(required)**: - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: - `fullName` (string) **(required)**: ### 400: Invalid request body ### 401: Unauthorized ### 403: Access denied to this patient ### 404: Patient not found ### 409: A patient with this external ID already exists for this clinic ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/patients/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "firstName": "string", "lastName": "string" }' ``` --- # List labs with access to a patient `GET https://api.guidelab.co/patients/{id}/lab-access` List labs with effective access through either an explicit live grant or the active partnership's share-all-patients policy. Clinic only - the patient must belong to the current clinic. Documentation: https://docs.guidelab.co/api-reference/patients/listPatientLabAccess ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Patient ID ## Responses ### 200: List of labs with effective access and its source - `labs` (object[]) **(required)**: - `labId` (string) **(required)**: - `labName` (string,null) **(required)**: - `grantedAt` (object): - `accessSource` (string) **(required)**: Values: `explicit`, `partnership` - `grantSource` (string,null) **(required)**: Values: `manual`, `order`, `patient_creation`, `null` - `sourceOrderId` (string,null) **(required)**: ### 401: Unauthorized ### 403: Forbidden - clinic only ### 404: Patient not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/patients/{id}/lab-access" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Grant lab access to a patient `POST https://api.guidelab.co/patients/{id}/lab-access` Grant a specific lab explicit access to a patient record. The lab must have an active partnership with the clinic. Clinic only - the patient must belong to the current clinic. Idempotent - granting access twice is a no-op. Documentation: https://docs.guidelab.co/api-reference/patients/grantPatientLabAccess ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Patient ID ## Request Body Content-Type: `application/json` - `labId` (string) **(required)**: ## Responses ### 201: Lab access granted to patient - `success` (boolean) **(required)**: Values: `true` ### 400: Invalid request body ### 401: Unauthorized ### 403: No active partnership with this lab ### 404: Patient not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/patients/{id}/lab-access" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "labId": "string" }' ``` --- # Revoke lab access to a patient `DELETE https://api.guidelab.co/patients/{id}/lab-access` Revoke a lab's effective access while retaining grant and revocation audit evidence. Under partnership-wide sharing this creates a per-patient exclusion. Active and suspended partnership epochs are supported. Clinic only. Documentation: https://docs.guidelab.co/api-reference/patients/revokePatientLabAccess ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Patient ID ## Request Body Content-Type: `application/json` - `labId` (string) **(required)**: ## Responses ### 200: Lab access revoked from patient - `success` (boolean) **(required)**: Values: `true` ### 400: Invalid request body ### 401: Unauthorized ### 403: Forbidden - clinic only ### 404: Patient not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/patients/{id}/lab-access" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "labId": "string" }' ``` --- # List partnerships for the current organization `GET https://api.guidelab.co/partnerships` Retrieve a paginated list of partnerships with order statistics. Labs see clinic partners, clinics see lab partners. Supports search, status filtering, practice group filtering, and configurable sorting. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/partnerships/listPartnerships ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Page number Default: `1` - `limit` (integer) (in: query): Items per page Default: `20` - `search` (string) (in: query): Search term for partner name, email, or city - `status` () (in: query): Filter by partnership status Default: `all` - `practiceGroupId` (string) (in: query): Filter by practice group ID - `sortBy` (string) (in: query): Field to sort by Values: `name`, `totalOrders`, `activeOrders`, `lastOrderDate`, `createdAt` Default: `name` - `sortOrder` (string) (in: query): Sort direction Values: `asc`, `desc` Default: `asc` ## Responses ### 200: Paginated list of partnerships with order statistics - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `partnerId` (string) **(required)**: - `partnerName` (string,null) **(required)**: - `partnerEmail` (string,null) **(required)**: - `partnerPhone` (string,null) **(required)**: - `partnerCity` (string,null) **(required)**: - `partnerLogo` (string,null) **(required)**: - `status` (string) **(required)**: - `initiatedBy` (string,null) **(required)**: - `totalOrders` (number) **(required)**: - `activeOrders` (number) **(required)**: - `lastOrderDate` (string,null) **(required)**: - `practiceGroupId` (string,null) **(required)**: - `practiceGroupName` (string,null) **(required)**: - `billingOwnerId` (string,null) **(required)**: - `partnerProvisioningStatus` (string) **(required)**: Values: `claimed`, `pending_claim`, `managed`, `abandoned` - `claimKind` (string,null) **(required)**: Values: `provisional_owner`, `managed_owner`, `null` - `createdAt` (string) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 401: Unauthorized ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/partnerships" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Search for potential partners `GET https://api.guidelab.co/partnerships/search` Search for discoverable organizations to form new partnerships with. Excludes existing partners. Supports text search, organization type filtering, and geographic bounding box filtering. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/partnerships/searchPartners ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `q` (string) (in: query): Search query for organization name - `type` (string) **(required)** (in: query): Organization type to search for Values: `lab`, `clinic` - `minLat` (number) (in: query): Minimum latitude for geographic bounding box - `maxLat` (number) (in: query): Maximum latitude for geographic bounding box - `minLng` (number) (in: query): Minimum longitude for geographic bounding box - `maxLng` (number) (in: query): Maximum longitude for geographic bounding box - `limit` (integer) (in: query): Maximum number of results to return Default: `50` - `page` (integer) (in: query): Page number Default: `1` - `categories` (string) (in: query): Comma-separated list of service/category name fragments to filter by (lab search only). Each fragment is matched case-insensitively against the lab's product category names. - `sortBy` (string) (in: query): Sort order. 'distance' requires clinicLat and clinicLng; falls back to 'name' otherwise. Values: `name`, `distance` Default: `name` - `clinicLat` (number) (in: query): Requesting organization's latitude (for distance sort). - `clinicLng` (number) (in: query): Requesting organization's longitude (for distance sort). ## Responses ### 200: Paginated search results of potential partner organizations - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string,null) **(required)**: - `city` (string,null) **(required)**: - `country` (string,null) **(required)**: - `logo` (string,null) **(required)**: - `latitude` (string,null) **(required)**: - `longitude` (string,null) **(required)**: - `description` (string,null) **(required)**: - `hasCoverImage` (boolean) **(required)**: - `categories` (string[]) **(required)**: - `partnershipStatus` (string,null) **(required)**: - `partnershipId` (string,null) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 401: Unauthorized ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/partnerships/search" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Invite a new clinic to GuideLab `POST https://api.guidelab.co/partnerships/invite` Create a new clinic organization and pending partnership in one step. Sends an invitation email to the clinic manager. Lab only. Documentation: https://docs.guidelab.co/api-reference/partnerships/inviteClinic ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `clinicName` (string) **(required)**: - `address` (string): - `city` (string): - `state` (string): - `postcode` (string): - `country` (string): - `latitude` (number,null): - `longitude` (number,null): - `companyNumber` (object): - `taxRegistrationNumber` (string): - `eInvoiceCode` (object): - `certifiedEmail` (object): - `managerEmail` (string) **(required)**: [email] - `managerName` (string): ## Responses ### 201: Clinic organization created and partnership established - `organization` (object): - `partnership` (object): ### 400: Invalid request or clinic name already exists ### 401: Unauthorized ### 403: Forbidden - lab only ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/partnerships/invite" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "clinicName": "string", "managerEmail": "string" }' ``` --- # Invite an owner to claim a lab-managed clinic `POST https://api.guidelab.co/partnerships/{id}/invite-owner` Starts an ownership handoff for an imported clinic while preserving its existing active partnership and history. Documentation: https://docs.guidelab.co/api-reference/partnerships/inviteManagedClinicOwner ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `managerEmail` (string) **(required)**: [email] - `managerName` (string): ## Responses ### 201: Ownership claim invitation created - `success` (boolean) **(required)**: Values: `true` - `organizationId` (string) **(required)**: ### 400: Invalid ownership handoff ### 401: Unauthorized ### 403: Lab manager required ### 404: Managed clinic partnership not found ### 409: Clinic state changed concurrently ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/partnerships/{id}/invite-owner" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "managerEmail": "string", "managerName": "string" }' ``` --- # Cancel a managed clinic ownership handoff `POST https://api.guidelab.co/partnerships/{id}/claim/cancel` Documentation: https://docs.guidelab.co/api-reference/partnerships/cancelManagedClinicClaim ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Ownership handoff canceled ### 401: Unauthorized ### 403: Lab manager required ### 404: Pending managed claim not found ### 409: Claim resolved concurrently ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/partnerships/{id}/claim/cancel" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Request a partnership with another organization `POST https://api.guidelab.co/partnerships/request` Send a partnership request to another organization. The target must be a different type (lab requests clinic, clinic requests lab). Sends a notification to the target organization's owners. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/partnerships/requestPartnership ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `targetOrgId` (string) **(required)**: ## Responses ### 201: Partnership request created with pending status - `partnership` (object): ### 400: Invalid request or same organization type ### 401: Unauthorized ### 404: Target organization not found ### 409: Partnership already exists between these organizations ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/partnerships/request" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "targetOrgId": "string" }' ``` --- # Get partnership detail view `GET https://api.guidelab.co/partnerships/{id}` Retrieve full partnership details including partner organization info, order/patient statistics, practice group, and gallery images. Only accessible by organizations that are part of the partnership. Documentation: https://docs.guidelab.co/api-reference/partnerships/getPartnership ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Partnership ID ## Responses ### 200: Full partnership detail with partner info and statistics - `partnershipId` (string) **(required)**: - `partnerId` (string) **(required)**: - `partnerType` (string) **(required)**: Values: `lab`, `clinic` - `status` (string) **(required)**: - `initiatedBy` (string,null) **(required)**: - `practiceGroupName` (string,null) **(required)**: - `priceListId` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `partner` (object) **(required)**: - `name` (string,null) **(required)**: - `logo` (string,null) **(required)**: - `email` (string,null) **(required)**: - `phone` (string,null) **(required)**: - `billingEmail` (string,null) **(required)**: - `address` (string,null) **(required)**: - `addressLine2` (string,null) **(required)**: - `city` (string,null) **(required)**: - `postcode` (string,null) **(required)**: - `country` (string,null) **(required)**: - `website` (string,null) **(required)**: - `companyNumber` (string,null) **(required)**: - `taxRegistrationNumber` (string,null) **(required)**: - `description` (string,null) **(required)**: - `hasCoverImage` (boolean) **(required)**: - `latitude` (string,null) **(required)**: - `longitude` (string,null) **(required)**: - `stats` (object) **(required)**: - `totalOrders` (number) **(required)**: - `activeOrders` (number) **(required)**: - `totalPatients` (number,null) **(required)**: - `gallery` (object[]) **(required)**: - `id` (string) **(required)**: - `sortOrder` (number,null) **(required)**: ### 401: Unauthorized ### 404: Partnership not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/partnerships/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get clinic detail view for a partnership `GET https://api.guidelab.co/partnerships/{id}/detail` Retrieve detailed clinic information for a partnership, including clinic contact info, order statistics, and patient count. Lab only - uses the partnership ID as the path parameter. Documentation: https://docs.guidelab.co/api-reference/partnerships/getPartnershipClinicDetail ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Partnership ID ## Responses ### 200: Clinic detail with contact info, order and patient stats - `id` (string) **(required)**: - `clinicId` (string) **(required)**: - `status` (string) **(required)**: - `practiceGroupName` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `clinic` (object) **(required)**: - `name` (string,null) **(required)**: - `email` (string,null) **(required)**: - `phone` (string,null) **(required)**: - `address` (string,null) **(required)**: - `addressLine2` (string,null) **(required)**: - `city` (string,null) **(required)**: - `postcode` (string,null) **(required)**: - `country` (string,null) **(required)**: - `website` (string,null) **(required)**: - `billingEmail` (string,null) **(required)**: - `companyNumber` (string,null) **(required)**: - `taxRegistrationNumber` (string,null) **(required)**: - `stats` (object) **(required)**: - `totalOrders` (number) **(required)**: - `activeOrders` (number) **(required)**: - `totalPatients` (number) **(required)**: ### 401: Unauthorized ### 403: Forbidden ### 404: Partnership not found ### 409: Partnership invitation was resolved concurrently ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/partnerships/{id}/detail" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Accept a pending partnership request `POST https://api.guidelab.co/partnerships/{id}/accept` Accept a pending partnership request. Only the receiving party can accept (e.g., if a lab initiated, only the clinic can accept). Sends a notification to the initiating party. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/partnerships/acceptPartnership ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Partnership ID ## Responses ### 200: Partnership accepted and activated - `partnership` (object): ### 400: Partnership is not pending ### 401: Unauthorized ### 403: Forbidden ### 404: Partnership not found ### 409: Partnership invitation was resolved concurrently ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/partnerships/{id}/accept" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Cancel a pending partnership request `POST https://api.guidelab.co/partnerships/{id}/cancel` Cancel a pending partnership request. Only the initiating party can cancel. Also cancels any associated pending invitations. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/partnerships/cancelPartnership ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Partnership ID ## Responses ### 200: Partnership request cancelled and deleted - `success` (boolean) **(required)**: Values: `true` - `message` (string) **(required)**: ### 400: Partnership is not pending ### 401: Unauthorized ### 403: Forbidden ### 404: Partnership not found ### 409: Partnership invitation was resolved concurrently ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/partnerships/{id}/cancel" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Reject a pending partnership request `POST https://api.guidelab.co/partnerships/{id}/reject` Reject a pending partnership request. Only the receiving party can reject. Sends a notification to the initiating party and retains the rejected relationship epoch as immutable history. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/partnerships/rejectPartnership ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Partnership ID ## Responses ### 200: Partnership rejected and retained as history - `success` (boolean) **(required)**: Values: `true` - `message` (string) **(required)**: ### 400: Partnership is not pending ### 401: Unauthorized ### 403: Forbidden ### 404: Partnership not found ### 409: Partnership status changed concurrently ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/partnerships/{id}/reject" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Reactivate a suspended partnership `POST https://api.guidelab.co/partnerships/{id}/reactivate` Reactivate a suspended partnership back to active status. Either party in the partnership can reactivate it. Sends a notification to the other party. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/partnerships/reactivatePartnership ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Partnership ID ## Responses ### 200: Partnership reactivated to active status - `partnership` (object): ### 400: Partnership is not suspended ### 401: Unauthorized ### 403: Forbidden ### 404: Partnership not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/partnerships/{id}/reactivate" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Resend partnership invitation email `POST https://api.guidelab.co/partnerships/{id}/resend` Resend the invitation email for a pending partnership. Extends the invitation expiry by 30 days. Lab only - only the lab that initiated the partnership can resend. Documentation: https://docs.guidelab.co/api-reference/partnerships/resendPartnershipInvite ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Partnership ID ## Responses ### 200: Invitation email resent with extended expiry - `success` (boolean) **(required)**: Values: `true` ### 400: Partnership is not pending ### 401: Unauthorized ### 403: Forbidden ### 404: Partnership or invitation not found ### 429: Partnership invitation send budget exceeded ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/partnerships/{id}/resend" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get share-all-patients setting `GET https://api.guidelab.co/partnerships/{id}/share-all-patients` Check whether the share-all-patients setting is enabled for a partnership. Both parties of the partnership can read this setting. Documentation: https://docs.guidelab.co/api-reference/partnerships/getShareAllPatients ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Partnership ID ## Responses ### 200: Current share-all-patients boolean value - `shareAllPatients` (boolean) **(required)**: ### 401: Unauthorized ### 403: Forbidden ### 404: Partnership not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/partnerships/{id}/share-all-patients" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update share-all-patients setting `PUT https://api.guidelab.co/partnerships/{id}/share-all-patients` Toggle whether all patients are automatically shared with the lab partner. When disabled, labs only see patients with explicit lab access grants. Clinic only. Documentation: https://docs.guidelab.co/api-reference/partnerships/updateShareAllPatients ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Partnership ID ## Request Body Content-Type: `application/json` - `shareAllPatients` (boolean) **(required)**: ## Responses ### 200: Setting updated - `shareAllPatients` (boolean) **(required)**: ### 401: Unauthorized ### 403: Forbidden ### 404: Partnership not found ### 409: Partnership is not active or changed concurrently ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/partnerships/{id}/share-all-patients" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "shareAllPatients": true }' ``` --- # Suspend an active partnership `POST https://api.guidelab.co/partnerships/{id}/suspend` Suspend an active partnership. Either party can suspend. Sends a notification to the other party. The partnership can later be reactivated. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/partnerships/suspendPartnership ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Partnership ID ## Responses ### 200: Partnership suspended - `partnership` (object): ### 400: Partnership is not active ### 401: Unauthorized ### 403: Forbidden ### 404: Partnership not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/partnerships/{id}/suspend" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Terminate a partnership `POST https://api.guidelab.co/partnerships/{id}/terminate` Permanently terminate a partnership. Either party can terminate. Sends a notification to the other party. This action is not reversible. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/partnerships/terminatePartnership ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Partnership ID ## Responses ### 200: Partnership terminated permanently - `partnership` (object): ### 400: Partnership is already terminated ### 401: Unauthorized ### 403: Forbidden ### 404: Partnership not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/partnerships/{id}/terminate" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Compliance documents the partner lab shares with this clinic `GET https://api.guidelab.co/partnerships/{id}/compliance-documents` Empty unless the partnership is active. Only documents the lab chose to share whose type is meant for customers are listed, each at its latest revision. Documentation: https://docs.guidelab.co/api-reference/partnerships/listPartnershipComplianceDocuments ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Shared documents - `documents` (object[]) **(required)**: - `id` (string) **(required)**: - `typeKey` (string) **(required)**: - `name` (string) **(required)**: - `revision` (object) **(required)**: - `number` (integer) **(required)**: - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `createdAt` (string) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: ### 404: Partnership not found - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/partnerships/{id}/compliance-documents" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # The latest revision of a document the partner lab shares `GET https://api.guidelab.co/partnerships/{id}/compliance-documents/{documentId}` Documentation: https://docs.guidelab.co/api-reference/partnerships/getPartnershipComplianceDocument ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `documentId` (string) **(required)** (in: path): ## Responses ### 200: The revision, with its content unless it is a file - `number` (integer) **(required)**: - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `createdAt` (string) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `content` (object,null) **(required)**: - `version` (number) **(required)**: Values: `1` - `doc` (object) **(required)**: ### 404: Document not found or not shared with this clinic - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/partnerships/{id}/compliance-documents/{documentId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # The file of a shared document's latest revision, streamed inline `GET https://api.guidelab.co/partnerships/{id}/compliance-documents/{documentId}/file` Documentation: https://docs.guidelab.co/api-reference/partnerships/getPartnershipComplianceDocumentFile ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `documentId` (string) **(required)** (in: path): ## Responses ### 200: The file (PDF, PNG, JPEG or WebP), private and never cached ### 404: No shared file for this clinic - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/partnerships/{id}/compliance-documents/{documentId}/file" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get payment settings for a partnership `GET https://api.guidelab.co/partnership-payment-settings/{partnershipId}` Retrieve payment policy settings for a partnership, including the effective policy (partnership override or lab default) and Stripe Connect status. Available to both parties of the partnership. Callers without the finance:view capability receive only effectivePolicy, paymentUnavailable and labStripeAccountId. Documentation: https://docs.guidelab.co/api-reference/partnership-payment-settings/getPartnershipPaymentSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `partnershipId` (string) **(required)** (in: path): Partnership ID ## Responses ### 200: Payment settings with effective policy and Stripe Connect info - `paymentPolicy` (string,null): - `upfrontPaymentDiscountPercent` (string,null): - `labDefaultUpfrontPaymentDiscountPercent` (string): - `effectiveUpfrontPaymentDiscountPercent` (string,null): - `invoiceDuePolicy` (string,null): Values: `net_days`, `day_of_month`, `null` - `invoiceTermDays` (integer,null): - `invoiceDueDay` (integer,null): - `invoiceDueMonthRule` (string,null): Values: `next_occurrence`, `following_month`, `null` - `creditHoldEnabled` (boolean,null): - `effectivePolicy` (string) **(required)**: - `paymentUnavailable` (boolean) **(required)**: - `effectiveInvoiceDuePolicy` (object): - `effectiveInvoiceTermDays` (integer,null): - `effectiveCreditHoldEnabled` (boolean): - `creditHoldActive` (boolean): - `labDefault` (string): - `labDefaultInvoiceDuePolicy` (object): - `labDefaultInvoiceTermDays` (integer,null): - `labDefaultCreditHoldEnabled` (boolean): - `labStripeAccountId` (string,null) **(required)**: - `labTaxPolicyConfigured` (boolean): - `autopayEnabled` (boolean): - `autopayConsentedAt` (string,null): [date-time] ### 401: Unauthorized ### 404: Partnership not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/partnership-payment-settings/{partnershipId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update payment settings for a partnership `PUT https://api.guidelab.co/partnership-payment-settings/{partnershipId}` Set or clear a payment policy override for a partnership. Setting to null removes the override and falls back to the lab's default policy. Only the lab owner of the partnership may change it. Documentation: https://docs.guidelab.co/api-reference/partnership-payment-settings/updatePartnershipPaymentSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `partnershipId` (string) **(required)** (in: path): Partnership ID ## Request Body Content-Type: `application/json` - `paymentPolicy` (string,null): Values: `pay_on_invoice`, `pay_in_advance`, `pay_now_or_later`, `null` - `upfrontPaymentDiscountPercent` (string,null): - `invoiceDuePolicy` (string,null): Values: `net_days`, `day_of_month`, `null` - `invoiceTermDays` (integer,null): - `invoiceDueDay` (integer,null): - `invoiceDueMonthRule` (string,null): Values: `next_occurrence`, `following_month`, `null` - `creditHoldEnabled` (boolean,null): ## Responses ### 200: Settings updated - `success` (boolean) **(required)**: Values: `true` ### 400: Invalid payment policy ### 401: Unauthorized ### 403: Forbidden ### 404: Partnership not found ### 409: Partnership is not active, or an upfront policy needs the lab's sales tax policy configured first (code tax_policy_unconfigured) ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/partnership-payment-settings/{partnershipId}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # List practice groups `GET https://api.guidelab.co/practice-groups` Retrieve a paginated list of practice groups for the current lab. Optionally includes partnership counts and inactive groups. Lab only. Documentation: https://docs.guidelab.co/api-reference/practice-groups/listPracticeGroups ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` () (in: query): Default: `false` - `includePartnershipCount` () (in: query): Default: `true` - `search` (string) (in: query): - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `50` ## Responses ### 200: List of practice groups - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `useCustomExport` (boolean) **(required)**: - `exportConfig` (object): - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `partnershipCount` (number): - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 401: Unauthorized ### 403: Forbidden ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/practice-groups" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a practice group `POST https://api.guidelab.co/practice-groups` Create a new practice group to organize clinic partnerships. Supports custom export configurations. Lab only. Documentation: https://docs.guidelab.co/api-reference/practice-groups/createPracticeGroup ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `description` (string): - `useCustomExport` (boolean): (default: `false`) - `exportConfig` (object): - `fields` (object[]): (default: ``) - `key` (string) **(required)**: - `label` (string) **(required)**: - `enabled` (boolean): (default: `true`) - `sortOrder` (integer): (default: `0`) - `format` (string): (default: `csv`) Values: `csv`, `xlsx`, `pdf` - `includeHeaders` (boolean): (default: `true`) - `dateFormat` (string): (default: `YYYY-MM-DD`) - `sortOrder` (integer): (default: `0`) - `isActive` (boolean): (default: `true`) ## Responses ### 201: Practice group created - `practiceGroup` (object): ### 400: Invalid request body ### 401: Unauthorized ### 403: Forbidden ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/practice-groups" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string", "useCustomExport": true, "exportConfig": { "fields": [ { "key": "string", "label": "string", "enabled": true, "sortOrder": 0 } ], "format": "csv", "includeHeaders": true, "dateFormat": "string" }, "sortOrder": 0, "isActive": true }' ``` --- # Get a practice group by ID `GET https://api.guidelab.co/practice-groups/{id}` Retrieve a practice group with partnership count. Optionally includes the full list of partnerships in the group. Lab only. Documentation: https://docs.guidelab.co/api-reference/practice-groups/getPracticeGroup ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `includePartnerships` (string) (in: query): ## Responses ### 200: Practice group - `practiceGroup` (object): ### 401: Unauthorized ### 403: Forbidden ### 404: Practice group not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/practice-groups/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Deactivate a practice group `DELETE https://api.guidelab.co/practice-groups/{id}` Soft-delete a practice group by setting it to inactive. Active partnerships in the group are unassigned first; terminal epochs retain their historical grouping. Lab manager only. Documentation: https://docs.guidelab.co/api-reference/practice-groups/deletePracticeGroup ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Practice group deactivated - `practiceGroup` (object): - `message` (string) **(required)**: ### 401: Unauthorized ### 403: Forbidden ### 404: Practice group not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/practice-groups/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a practice group `PUT https://api.guidelab.co/practice-groups/{id}` Update one or more fields of a practice group. Supports partial updates. Lab only. Documentation: https://docs.guidelab.co/api-reference/practice-groups/updatePracticeGroup ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `name` (string): - `description` (string): - `useCustomExport` (boolean): - `exportConfig` (object): - `fields` (object[]): (default: ``) - `key` (string) **(required)**: - `label` (string) **(required)**: - `enabled` (boolean): (default: `true`) - `sortOrder` (integer): (default: `0`) - `format` (string): (default: `csv`) Values: `csv`, `xlsx`, `pdf` - `includeHeaders` (boolean): (default: `true`) - `dateFormat` (string): (default: `YYYY-MM-DD`) - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 200: Practice group updated - `practiceGroup` (object): ### 400: Invalid request body ### 401: Unauthorized ### 403: Forbidden ### 404: Practice group not found ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/practice-groups/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string", "useCustomExport": true, "exportConfig": { "fields": [ { "key": "string", "label": "string", "enabled": true, "sortOrder": 0 } ], "format": "csv", "includeHeaders": true, "dateFormat": "string" }, "sortOrder": 0, "isActive": true }' ``` --- # List partnerships in a practice group `GET https://api.guidelab.co/practice-groups/{id}/partnerships` Retrieve active partnerships assigned to a specific practice group, including clinic names and logos. Lab only. Documentation: https://docs.guidelab.co/api-reference/practice-groups/listPracticeGroupPartnerships ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: List of partnerships - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `clinicId` (string) **(required)**: - `status` (string) **(required)**: - `initiatedBy` (string,null) **(required)**: - `practiceGroupId` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `clinicName` (string,null) **(required)**: - `clinicLogo` (string,null) **(required)**: ### 401: Unauthorized ### 403: Forbidden ### 404: Practice group not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/practice-groups/{id}/partnerships" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Assign partnerships to a practice group `POST https://api.guidelab.co/practice-groups/{id}/partnerships` Assign one or more active partnerships to an active practice group. All partnerships must belong to the current lab. Lab manager only. Documentation: https://docs.guidelab.co/api-reference/practice-groups/assignPracticeGroupPartnerships ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `partnershipIds` (string[]) **(required)**: ## Responses ### 200: Partnerships assigned - `data` (array) **(required)**: - `message` (string) **(required)**: ### 400: Invalid request or partnerships not found ### 401: Unauthorized ### 403: Forbidden ### 404: Practice group not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/practice-groups/{id}/partnerships" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "partnershipIds": [ "string" ] }' ``` --- # Remove a partnership from a practice group `DELETE https://api.guidelab.co/practice-groups/{id}/partnerships/{partnershipId}` Remove a single active partnership from a practice group by setting its practiceGroupId to null. The partnership itself is not deleted. Lab manager only. Documentation: https://docs.guidelab.co/api-reference/practice-groups/removePracticeGroupPartnership ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `partnershipId` (string) **(required)** (in: path): ## Responses ### 200: Partnership removed from group - `partnership` (object): - `message` (string) **(required)**: ### 401: Unauthorized ### 403: Forbidden ### 404: Practice group or partnership not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/practice-groups/{id}/partnerships/{partnershipId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Organization Onboarding `GET https://api.guidelab.co/organization/onboarding` Documentation: https://docs.guidelab.co/api-reference/organization-onboarding/getOrganizationOnboarding ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Persisted onboarding snapshot - `onboarding` (object): ### 403: Organization owner required ### 404: Onboarding is not required ## Example ```bash curl -X GET "https://api.guidelab.co/organization/onboarding" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Save Organization Onboarding Step `PUT https://api.guidelab.co/organization/onboarding/step` Documentation: https://docs.guidelab.co/api-reference/organization-onboarding/saveOrganizationOnboardingStep ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `step` (string) **(required)**: Values: `identity`, `regional`, `location`, `tax`, `subscription` - `direction` (string) **(required)**: Values: `forward`, `back` - `data` (object): ## Responses ### 200: Updated onboarding snapshot - `onboarding` (object): ### 400: Invalid or out-of-order onboarding step ### 403: Organization owner required ### 404: Onboarding is not required ### 409: Organization identity conflicts ## Example ```bash curl -X PUT "https://api.guidelab.co/organization/onboarding/step" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "step": "identity", "direction": "forward", "data": "string" }' ``` --- # Complete Clinic Organization Onboarding `POST https://api.guidelab.co/organization/onboarding/complete` Documentation: https://docs.guidelab.co/api-reference/organization-onboarding/completeClinicOrganizationOnboarding ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Clinic onboarding completed ### 400: Required clinic details are incomplete ### 403: Clinic owner required ### 404: Onboarding is not required ## Example ```bash curl -X POST "https://api.guidelab.co/organization/onboarding/complete" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Onboarding Subscription Checkout `POST https://api.guidelab.co/organization/onboarding/subscription-checkout` Documentation: https://docs.guidelab.co/api-reference/organization-onboarding/createOnboardingSubscriptionCheckout ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `plan` (string) **(required)**: Values: `base`, `growth`, `scale` - `interval` (string) **(required)**: Values: `month`, `year` - `returnUrl` (string) **(required)**: [uri] - `cancelUrl` (string) **(required)**: [uri] ## Responses ### 200: Stripe Checkout URL - `url` (string) **(required)**: [uri] ### 400: Plan selection is not persisted ### 403: Lab owner required ### 404: Onboarding is not required ### 409: The lab already has an active or unreviewed platform subscription ### 502: Stripe Checkout could not be created ### 503: Billing verification is temporarily unavailable ## Example ```bash curl -X POST "https://api.guidelab.co/organization/onboarding/subscription-checkout" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "plan": "base", "interval": "month", "returnUrl": "https://example.com", "cancelUrl": "https://example.com" }' ``` --- # Check organization name availability `GET https://api.guidelab.co/organization/check-availability` Check whether an organization name is already taken. No authentication required. Used during onboarding. Documentation: https://docs.guidelab.co/api-reference/organization/checkOrgNameAvailability ## Parameters - `name` (string) (in: query): - `type` (string) (in: query): ## Responses ### 200: Availability result - `available` (boolean) **(required)**: - `name` (string): - `message` (string): ### 400: Invalid input ### 429: Organization lookup limit reached ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/organization/check-availability" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Check organization slug availability `GET https://api.guidelab.co/organization/check-slug` Check whether an organization slug is already taken. Requires user authentication. Used during onboarding. Documentation: https://docs.guidelab.co/api-reference/organization/checkOrgSlugAvailability ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `slug` (string) (in: query): ## Responses ### 200: Slug availability - `available` (boolean) **(required)**: ### 400: Invalid input ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/organization/check-slug" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a new organization `POST https://api.guidelab.co/organization/create` Create a new lab or clinic organization. The current user becomes the owner. Labs get default treatment phases and steps. Sets the new org as the user's active organization. Documentation: https://docs.guidelab.co/api-reference/organization/createOrganization ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `slug` (string): - `type` (string) **(required)**: Values: `lab`, `clinic` - `phone` (string): - `address` (string): - `city` (string): - `postcode` (string): - `website` (object): ## Responses ### 200: Organization created - `success` (boolean) **(required)**: - `organization` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `slug` (string) **(required)**: - `organizationType` (string) **(required)**: ### 400: Invalid input ### 401: Unauthorized ### 409: Organization slug already exists ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/organization/create" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "type": "lab" }' ``` --- # List pending join requests `GET https://api.guidelab.co/organization/join-request` List all pending join requests for the current organization. Only organization owners can view these. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/organization/listJoinRequests ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of join requests - `requests` (object[]) **(required)**: - `id` (string) **(required)**: - `userId` (string) **(required)**: - `status` (string) **(required)**: - `message` (string,null) **(required)**: - `createdAt` (object): - `userName` (string) **(required)**: - `userEmail` (string) **(required)**: ### 401: Unauthorized ### 403: Forbidden ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/organization/join-request" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Request to join an organization `POST https://api.guidelab.co/organization/join-request` Submit a request to join an organization. Sends a notification to the organization's owners. Prevents duplicate requests. Documentation: https://docs.guidelab.co/api-reference/organization/createJoinRequest ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `organizationId` (string) **(required)**: - `message` (string): ## Responses ### 201: Join request created - `success` (boolean) **(required)**: - `joinRequest` (object) **(required)**: - `id` (string) **(required)**: - `status` (string) **(required)**: - `createdAt` (object): ### 400: Invalid input ### 401: Unauthorized ### 404: Organization not found ### 409: Already a member or request pending ### 429: Join request creation budget exceeded ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/organization/join-request" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "organizationId": "string", "message": "string" }' ``` --- # Approve or reject a join request `PATCH https://api.guidelab.co/organization/join-request/{id}` Approve or reject a pending join request. Owners and managers choose an assignable organization role; omitted roles use the default operational role. Documentation: https://docs.guidelab.co/api-reference/organization/processJoinRequest ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `action` (string) **(required)**: Values: `approve`, `reject` - `role` (string): Values: `owner`, `admin`, `staff`, `doctor`, `technician`, `accounts`, `reception` ## Responses ### 200: Join request processed - `success` (boolean) **(required)**: - `message` (string) **(required)**: ### 400: Invalid action ### 401: Unauthorized ### 403: Forbidden ### 404: Join request not found ### 500: Internal server error ## Example ```bash curl -X PATCH "https://api.guidelab.co/organization/join-request/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "action": "approve", "role": "owner" }' ``` --- # Resend a join request notification `POST https://api.guidelab.co/organization/join-request/{id}/resend` Resend notification emails to organization owners about a pending join request. Only the request author can resend. Documentation: https://docs.guidelab.co/api-reference/organization/resendJoinRequest ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Notification resent - `success` (boolean) **(required)**: ### 401: Unauthorized ### 404: Join request not found ### 429: Join request reminder budget exceeded ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/organization/join-request/{id}/resend" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Search organizations to join `GET https://api.guidelab.co/organization/join-search` Search for organizations the current user could request to join. Includes existing request and membership status for each result. Used during onboarding. Documentation: https://docs.guidelab.co/api-reference/organization/searchOrganizationsToJoin ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `q` (string) (in: query): - `type` (string) (in: query): - `limit` (string) (in: query): ## Responses ### 200: Search results - `organizations` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `city` (string,null) **(required)**: - `organizationType` (string,null) **(required)**: - `latitude` (string,null) **(required)**: - `longitude` (string,null) **(required)**: - `hasRequest` (boolean) **(required)**: - `isMember` (boolean) **(required)**: ### 400: Invalid input ### 401: Unauthorized ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/organization/join-search" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List organizations by type `GET https://api.guidelab.co/organization/list-by-type` List all organizations of a given type (lab or clinic). Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/organization/listOrganizationsByType ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `type` (string) (in: query): ## Responses ### 200: List of organizations - `organizations` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `slug` (string,null) **(required)**: - `city` (string,null) **(required)**: - `organizationType` (string,null) **(required)**: ### 400: Invalid type ### 401: Unauthorized ### 403: Forbidden ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/organization/list-by-type" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List current user's memberships `GET https://api.guidelab.co/organization/my-memberships` List all organizations the current user is a member of, including role, type, and logo. Used for org switching. Documentation: https://docs.guidelab.co/api-reference/organization/listMyMemberships ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of memberships - `memberships` (object[]) **(required)**: - `organizationId` (string) **(required)**: - `organizationName` (string) **(required)**: - `organizationType` (string,null) **(required)**: - `slug` (string,null) **(required)**: - `logo` (string,null) **(required)**: - `city` (string,null) **(required)**: - `role` (string) **(required)**: ### 401: Unauthorized ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/organization/my-memberships" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List current user's pending join requests `GET https://api.guidelab.co/organization/my-pending-requests` List all pending join requests submitted by the current user. Used for the org picker page. Documentation: https://docs.guidelab.co/api-reference/organization/listMyPendingRequests ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of pending join requests - `requests` (object[]) **(required)**: - `id` (string) **(required)**: - `orgName` (string) **(required)**: - `orgType` (string,null) **(required)**: - `createdAt` (object): ### 401: Unauthorized ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/organization/my-pending-requests" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Public organization search `GET https://api.guidelab.co/organization/public-search` Search organizations by name and type without authentication. Returns minimal info (id, name, city). Requires at least 2 characters. Used for pre-auth flows. Documentation: https://docs.guidelab.co/api-reference/organization/publicSearchOrganizations ## Parameters - `q` (string) (in: query): - `type` (string) (in: query): ## Responses ### 200: Search results - `organizations` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `city` (string,null) **(required)**: ### 400: Invalid input ### 429: Organization lookup limit reached ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/organization/public-search" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Search organizations `GET https://api.guidelab.co/organization/search` Search organizations by name with fuzzy matching. Can filter to only partnered organizations. Includes pending join request status. Requires user authentication. Documentation: https://docs.guidelab.co/api-reference/organization/searchOrganizations ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `q` (string) (in: query): - `type` (string) (in: query): - `partneredWith` (string) (in: query): - `limit` (string) (in: query): - `includePending` (string) (in: query): ## Responses ### 200: Search results - `organizations` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `city` (string,null) **(required)**: - `slug` (string,null) **(required)**: - `currency` (string) **(required)**: - `country` (string) **(required)**: - `hasRequest` (boolean) **(required)**: - `partnershipStatus` (string,null): Values: `active`, `pending`, `null` - `provisioningStatus` (string) **(required)**: Values: `claimed`, `pending_claim`, `managed`, `abandoned` ### 400: Invalid input ### 401: Unauthorized ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/organization/search" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get an organization by ID `GET https://api.guidelab.co/organization/{id}` Retrieve basic organization info. Access is limited to your own organization or partner organizations. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/organization/getOrganization ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Organization - `organization` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `slug` (string,null) **(required)**: - `type` (string,null) **(required)**: - `city` (string,null) **(required)**: ### 401: Unauthorized ### 403: Forbidden ### 404: Organization not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/organization/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List members of an organization `GET https://api.guidelab.co/organization/{id}/members` Retrieve members of an organization. Accessible to the org itself or active partner organizations. Supports search and role filtering. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/organization/listOrganizationMembers ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `q` (string) (in: query): - `role` (string) (in: query): ## Responses ### 200: List of members - `members` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `email` (string) **(required)**: - `role` (string) **(required)**: ### 401: Unauthorized ### 403: Forbidden ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/organization/{id}/members" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get public profile of an organization `GET https://api.guidelab.co/organization/{id}/profile` Retrieve the public-facing profile of a discoverable organization, including description, cover image, gallery, and product categories (for labs). Requires authentication. Documentation: https://docs.guidelab.co/api-reference/organization/getOrganizationProfile ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Organization profile - `id` (string) **(required)**: - `name` (string) **(required)**: - `organizationType` (string,null) **(required)**: - `logo` (string,null) **(required)**: - `description` (string,null) **(required)**: - `hasCoverImage` (boolean) **(required)**: - `email` (string,null) **(required)**: - `phone` (string,null) **(required)**: - `website` (string,null) **(required)**: - `latitude` (string,null) **(required)**: - `longitude` (string,null) **(required)**: - `gallery` (array) **(required)**: - `categories` (array) **(required)**: ### 401: Unauthorized ### 404: Organization not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/organization/{id}/profile" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get current organization subscription `GET https://api.guidelab.co/organization/subscription` Returns the latest subscription record for the active lab organization. Read-only and available even when billing is past due. Documentation: https://docs.guidelab.co/api-reference/organization/getCurrentOrganizationSubscription ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Latest organization subscription or null - `subscription` (object,null) **(required)**: - `id` (string) **(required)**: - `plan` (string) **(required)**: - `status` (string,null) **(required)**: - `periodStart` (string,null) **(required)**: - `periodEnd` (string,null) **(required)**: - `cancelAtPeriodEnd` (boolean,null) **(required)**: - `seats` (number,null) **(required)**: - `trialStart` (string,null) **(required)**: - `trialEnd` (string,null) **(required)**: - `hasBillingCustomer` (boolean) **(required)**: - `complimentary` (boolean) **(required)**: - `billingInterval` (string,null) **(required)**: - `billingCurrency` (string,null) **(required)**: - `catalogVersion` (string,null) **(required)**: - `storageAddOnUnits` (integer) **(required)**: - `pastDueAt` (string,null) **(required)**: - `pastDueGraceEndsAt` (string,null) **(required)**: - `pendingStorageAddOnUnits` (integer,null) **(required)**: - `pendingStorageAddOnAt` (string,null) **(required)**: - `pendingPlan` (string,null) **(required)**: Values: `base`, `growth`, `scale`, `null` - `pendingPlanBillingInterval` (string,null) **(required)**: Values: `month`, `year`, `null` - `pendingPlanAt` (string,null) **(required)**: - `usage` (object) **(required)**: - `cases` (object) **(required)**: - `windowStart` (string) **(required)**: - `windowEnd` (string) **(required)**: - `used` (integer) **(required)**: - `included` (integer,null) **(required)**: - `alert` (string) **(required)**: Values: `normal`, `warning`, `critical`, `over` - `nonBlocking` (boolean) **(required)**: Values: `true` - `storage` (object) **(required)**: - `usedBytes` (number) **(required)**: - `includedBytes` (number) **(required)**: - `addOnBytes` (number) **(required)**: - `alert` (string) **(required)**: Values: `normal`, `warning`, `critical`, `over` - `nonBlocking` (boolean) **(required)**: Values: `true` ### 401: Unauthorized ### 403: Lab organizations only ## Example ```bash curl -X GET "https://api.guidelab.co/organization/subscription" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update organization subscription storage add-on `PUT https://api.guidelab.co/organization/subscription/storage-add-on` Applies storage increases immediately with proration and schedules decreases for the next subscription renewal. GuideLab, not the Stripe portal, owns add-on quantity changes. Documentation: https://docs.guidelab.co/api-reference/organization/updateOrganizationSubscriptionStorageAddOn ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `idempotency-key` (string) **(required)** (in: header): Stable key reused only when retrying the exact same command body ## Request Body Content-Type: `application/json` - `units` (integer) **(required)**: ## Responses ### 200: Updated or scheduled storage quantity - `storageAddOnUnits` (integer) **(required)**: - `pendingStorageAddOnUnits` (integer,null) **(required)**: - `pendingStorageAddOnAt` (string,null) **(required)**: - `change` (string) **(required)**: Values: `unchanged`, `immediate_increase`, `scheduled_decrease`, `scheduled_decrease_cancelled` ### 401: Unauthorized ### 403: Lab owners only ### 409: No mutable platform subscription found ### 500: Stripe or catalog configuration unavailable ## Example ```bash curl -X PUT "https://api.guidelab.co/organization/subscription/storage-add-on" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "units": 0 }' ``` --- # Create organization billing portal session `POST https://api.guidelab.co/organization/subscription/billing-portal` Creates a Stripe billing portal session for the active lab organization so owners can update cards and manage subscription billing. Documentation: https://docs.guidelab.co/api-reference/organization/createOrganizationBillingPortalSession ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `returnUrl` (string): [uri] ## Responses ### 200: Billing portal URL - `url` (string) **(required)**: [uri] ### 401: Unauthorized ### 403: Lab owners only ### 404: No billing customer found ## Example ```bash curl -X POST "https://api.guidelab.co/organization/subscription/billing-portal" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "returnUrl": "https://example.com" }' ``` --- # Get the organization's active join code `GET https://api.guidelab.co/organization/join-code` Returns the current active shareable join code for the organization, or null if none exists. Owners and admins only. Documentation: https://docs.guidelab.co/api-reference/organization/getJoinCode ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: The active join code, or null - `joinCode` (object,null) **(required)**: - `code` (string) **(required)**: - `role` (string) **(required)**: Values: `staff`, `admin`, `technician`, `reception` - `expiresAt` (string,null) **(required)**: - `maxUses` (integer,null) **(required)**: - `useCount` (integer) **(required)**: - `createdAt` (string) **(required)**: ### 401: Unauthorized ### 403: Forbidden ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/organization/join-code" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Generate or rotate the organization's join code `POST https://api.guidelab.co/organization/join-code` Generates a fresh shareable join code, revoking any previous active code. Owners and admins only. Documentation: https://docs.guidelab.co/api-reference/organization/createJoinCode ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `role` (string): (default: `staff`) Values: `staff`, `admin`, `technician`, `reception` - `expiresInDays` (integer,null): - `maxUses` (integer,null): ## Responses ### 201: Join code created - `joinCode` (object) **(required)**: - `code` (string) **(required)**: - `role` (string) **(required)**: Values: `staff`, `admin`, `technician`, `reception` - `expiresAt` (string,null) **(required)**: - `maxUses` (integer,null) **(required)**: - `useCount` (integer) **(required)**: - `createdAt` (string) **(required)**: ### 400: Invalid input ### 401: Unauthorized ### 403: Forbidden ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/organization/join-code" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "role": "staff", "expiresInDays": "string", "maxUses": "string" }' ``` --- # Revoke the organization's active join code `DELETE https://api.guidelab.co/organization/join-code` Revokes the current active join code so it can no longer be redeemed. Owners and admins only. Documentation: https://docs.guidelab.co/api-reference/organization/revokeJoinCode ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Join code revoked - `success` (boolean) **(required)**: ### 401: Unauthorized ### 403: Forbidden ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/organization/join-code" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Redeem a join code to join an organization `POST https://api.guidelab.co/organization/join-code/redeem` Redeems a shareable join code and adds the current user as a member of the organization. Returns 404 with error 'invalid_code' for unknown codes so clients can fall back to invitation-id acceptance. Documentation: https://docs.guidelab.co/api-reference/organization/redeemJoinCode ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `code` (string) **(required)**: ## Responses ### 200: Joined (or already a member) - `success` (boolean) **(required)**: - `organizationId` (string) **(required)**: - `organizationType` (string) **(required)**: Values: `lab`, `clinic` - `alreadyMember` (boolean): ### 400: Invalid input ### 401: Unauthorized ### 404: Invalid code ### 409: Code revoked or usage limit reached ### 410: Code expired ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/organization/join-code/redeem" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "code": "string" }' ``` --- # Get organization closure status `GET https://api.guidelab.co/organization/closure` Returns the durable closure receipt for an active or closing organization. A narrow owner-membership check remains available after the organization is fenced. Documentation: https://docs.guidelab.co/api-reference/organization/getOrganizationClosureStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Organization closure status - `organizationId` (string) **(required)**: - `lifecycleStatus` (string) **(required)**: Values: `active`, `closing`, `closed` - `closureRequestedAt` (string,null) **(required)**: - `closureReason` (string,null) **(required)**: - `closedAt` (string,null) **(required)**: - `profileRedactionDueAt` (string,null) **(required)**: - `profileRedactedAt` (string,null) **(required)**: - `job` (object,null) **(required)**: - `status` (string) **(required)**: Values: `pending`, `processing`, `failed`, `completed` - `stage` (string) **(required)**: - `attempts` (number) **(required)**: - `availableAt` (string) **(required)**: - `lastError` (string,null) **(required)**: - `completedAt` (string,null) **(required)**: - `failedAt` (string,null) **(required)**: ### 401: Unauthorized ### 403: Organization owner access required ### 404: Organization not found ## Example ```bash curl -X GET "https://api.guidelab.co/organization/closure" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Request organization closure `POST https://api.guidelab.co/organization/closure` Fences the organization immediately and starts its bounded, resumable closure workflow. Replays are idempotent. Documentation: https://docs.guidelab.co/api-reference/organization/requestOrganizationClosure ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `reason` (string) **(required)**: ## Responses ### 202: Closure accepted or already in progress - `status` (string) **(required)**: Values: `requested`, `already_requested` ### 400: Invalid closure reason ### 401: Unauthorized ### 403: Organization owner access required ### 404: Organization not found ### 409: In-flight orders or shipments block closure ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/organization/closure" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "reason": "string" }' ``` --- # List retention holds `GET https://api.guidelab.co/organization/retention-holds` Lists a bounded set of immutable retention-hold evidence placed by the active organization. Documentation: https://docs.guidelab.co/api-reference/organization/listOrganizationRetentionHolds ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `status` (string) (in: query): Values: `live`, `released`, `all` Default: `live` - `limit` (integer) (in: query): Default: `50` ## Responses ### 200: Retention holds - `holds` (object[]) **(required)**: - `id` (string) **(required)**: - `holdingOrganizationId` (string) **(required)**: - `matterKey` (string) **(required)**: - `operation` (string) **(required)**: Values: `all`, `identity_erasure`, `object_retirement`, `organization_closure`, `conversation_deletion` - `reason` (string) **(required)**: - `scope` (object) **(required)**: - `kind` (string) **(required)**: Values: `organization`, `partnership`, `patient`, `order`, `invoice`, `statement`, `file`, `conversation`, `conversation_attachment`, `scan_inbox_item` - `id` (string) **(required)**: - `placedAt` (string) **(required)**: [date-time] - `placedBy` (string) **(required)**: - `releasedAt` (string,null) **(required)**: [date-time] - `releasedBy` (string,null) **(required)**: - `reviewDueAt` (string,null) **(required)**: [date-time] - `platformCustodyAt` (string,null) **(required)**: [date-time] ### 401: Unauthorized ### 403: Organization manager access required ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/organization/retention-holds" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Place a retention hold `POST https://api.guidelab.co/organization/retention-holds` Places immutable, controller-authorized hold evidence. Matter-key replays are idempotent only when the evidence is identical. Documentation: https://docs.guidelab.co/api-reference/organization/placeOrganizationRetentionHold ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `matterKey` (string) **(required)**: - `operation` (string) **(required)**: Values: `all`, `identity_erasure`, `object_retirement`, `organization_closure`, `conversation_deletion` - `reason` (string) **(required)**: - `scope` (object) **(required)**: - `kind` (string) **(required)**: Values: `organization`, `partnership`, `patient`, `order`, `invoice`, `statement`, `file`, `conversation`, `conversation_attachment`, `scan_inbox_item` - `id` (string) **(required)**: - `reviewDueAt` (string,null): [date-time] ## Responses ### 200: Retention hold placed or replayed - `status` (string) **(required)**: Values: `placed`, `already_placed` - `hold` (object) **(required)**: - `id` (string) **(required)**: - `holdingOrganizationId` (string) **(required)**: - `matterKey` (string) **(required)**: - `operation` (string) **(required)**: Values: `all`, `identity_erasure`, `object_retirement`, `organization_closure`, `conversation_deletion` - `reason` (string) **(required)**: - `scope` (object) **(required)**: - `kind` (string) **(required)**: Values: `organization`, `partnership`, `patient`, `order`, `invoice`, `statement`, `file`, `conversation`, `conversation_attachment`, `scan_inbox_item` - `id` (string) **(required)**: - `placedAt` (string) **(required)**: [date-time] - `placedBy` (string) **(required)**: - `releasedAt` (string,null) **(required)**: [date-time] - `releasedBy` (string,null) **(required)**: - `reviewDueAt` (string,null) **(required)**: [date-time] - `platformCustodyAt` (string,null) **(required)**: [date-time] ### 400: Invalid hold evidence or review date ### 401: Unauthorized ### 403: Organization does not control the requested scope ### 409: Matter key is bound to different evidence ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/organization/retention-holds" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "matterKey": "string", "operation": "all", "reason": "string", "scope": { "kind": "organization", "id": "string" }, "reviewDueAt": "string" }' ``` --- # Release a retention hold `POST https://api.guidelab.co/organization/retention-holds/{id}/release` Releases a hold owned by the active organization while preserving its immutable placement and release evidence. Documentation: https://docs.guidelab.co/api-reference/organization/releaseOrganizationRetentionHold ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Retention hold released or already released - `status` (string) **(required)**: Values: `released`, `already_released` ### 401: Unauthorized ### 403: Organization manager access required ### 404: Retention hold not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/organization/retention-holds/{id}/release" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Initialize organization settings defaults `POST https://api.guidelab.co/settings-defaults/initialize` Idempotently applies any unapplied settings-default revision using stable keys. The organization type and revision are read from a locked database row. New organizations run the same initializer during creation; this manager command repairs legacy or partially initialized organizations without recreating defaults intentionally removed after a revision was applied. Documentation: https://docs.guidelab.co/api-reference/organization-settings/initializeOrganizationSettingsDefaults ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Settings defaults initialized - `initialized` (object) **(required)**: - `shadeSystems` (number) **(required)**: - `implantSystems` (number) **(required)**: - `orderFilterPresets` (number) **(required)**: - `reports` (number) **(required)**: - `qcSettings` (number) **(required)**: - `productionSettings` (number) **(required)**: - `receivingCategories` (number) **(required)**: - `receivingSources` (number) **(required)**: - `inventoryCategories` (number) **(required)**: - `inventoryAdjustmentReasons` (number) **(required)**: - `holdReasons` (number) **(required)**: - `remakeReasons` (number) **(required)**: ### 401: Unauthorized ### 403: Organization owner or admin required ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/settings-defaults/initialize" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List team members `GET https://api.guidelab.co/team/members` Returns all members of the current organization with their name, email, role, and avatar. Documentation: https://docs.guidelab.co/api-reference/team/listTeamMembers ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of team members with user details - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `userId` (string) **(required)**: - `name` (string) **(required)**: - `email` (string) **(required)**: - `image` (string,null) **(required)**: - `role` (string) **(required)**: - `createdAt` (string) **(required)**: ### 401: Unauthorized — valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/team/members" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update team member role `PATCH https://api.guidelab.co/team/members/{id}` Updates a non-owner member's role. Only owners may promote another member to owner, retaining their own ownership. Owners and admins may assign other roles; doctor is clinic-only. Documentation: https://docs.guidelab.co/api-reference/team/updateTeamMemberRole ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Member ID ## Request Body Content-Type: `application/json` - `role` (string) **(required)**: Values: `owner`, `admin`, `staff`, `doctor`, `technician`, `accounts`, `reception` ## Responses ### 200: Member role updated successfully - `member` (object) **(required)**: - `id` (string) **(required)**: - `userId` (string) **(required)**: - `organizationId` (string) **(required)**: - `role` (string) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request, cannot change owner role, or cannot change own role ### 401: Unauthorized — valid session required ### 403: Forbidden — organization manager required ### 404: Member not found in this organization ### 429: Password reset email budget exceeded ## Example ```bash curl -X PATCH "https://api.guidelab.co/team/members/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "role": "owner" }' ``` --- # Remove team member `DELETE https://api.guidelab.co/team/members/{id}` Removes a member from the organization. Organization owners and admins may remove non-owner members, but cannot remove themselves. Documentation: https://docs.guidelab.co/api-reference/team/removeTeamMember ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Member ID ## Responses ### 200: Member removed successfully - `success` (boolean) **(required)**: ### 400: Cannot remove owner or yourself ### 401: Unauthorized — valid session required ### 403: Forbidden — organization manager required ### 404: Member not found in this organization ## Example ```bash curl -X DELETE "https://api.guidelab.co/team/members/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Transfer organization ownership `POST https://api.guidelab.co/team/members/{id}/transfer-ownership` Atomically promotes the selected member to owner and demotes the current owner to admin. Only the current owner may transfer ownership. Documentation: https://docs.guidelab.co/api-reference/team/transferOrganizationOwnership ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Member ID ## Responses ### 200: Ownership transferred - `ownerMemberId` (string) **(required)**: - `previousOwnerMemberId` (string) **(required)**: ### 400: Invalid ownership target ### 401: Unauthorized ### 403: Current organization owner required ### 404: Target member not found ## Example ```bash curl -X POST "https://api.guidelab.co/team/members/{id}/transfer-ownership" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Send password reset email to team member `POST https://api.guidelab.co/team/members/{id}/send-password-reset` Triggers a password reset email for the specified team member via Better Auth. Organization owners and admins may send password resets. Documentation: https://docs.guidelab.co/api-reference/team/sendPasswordResetEmail ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Member ID ## Responses ### 200: Password reset email sent - `success` (boolean) **(required)**: ### 401: Unauthorized — valid session required ### 403: Forbidden — organization manager required ### 404: Member not found in this organization ## Example ```bash curl -X POST "https://api.guidelab.co/team/members/{id}/send-password-reset" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List pending invitations `GET https://api.guidelab.co/team/invitations` Returns all pending team invitations for the current organization, including the inviter's name and expiration date. Documentation: https://docs.guidelab.co/api-reference/team/listPendingInvitations ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of pending invitations - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `email` (string) **(required)**: - `role` (string) **(required)**: - `status` (string) **(required)**: - `inviterId` (string) **(required)**: - `inviterName` (string) **(required)**: - `expiresAt` (string) **(required)**: - `createdAt` (string) **(required)**: - `inviteUrl` (string) **(required)**: ### 401: Unauthorized — valid session required ### 403: Forbidden — organization manager required ## Example ```bash curl -X GET "https://api.guidelab.co/team/invitations" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create and send team invitation `POST https://api.guidelab.co/team/invitations` Sends an invitation for an assignable organization role. Only owners may invite co-owners. Owners and admins may invite other roles; doctor is clinic-only. Documentation: https://docs.guidelab.co/api-reference/team/createTeamInvitation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `email` (string) **(required)**: [email] - `role` (string) **(required)**: Values: `owner`, `admin`, `staff`, `doctor`, `technician`, `accounts`, `reception` ## Responses ### 201: Invitation created and email sent - `success` (boolean) **(required)**: - `invitation` (object): ### 400: Invalid request, user already a member, or pending invitation exists ### 401: Unauthorized — valid session required ### 403: Forbidden — organization manager required ## Example ```bash curl -X POST "https://api.guidelab.co/team/invitations" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "email": "string", "role": "owner" }' ``` --- # Cancel a pending invitation `POST https://api.guidelab.co/team/invitations/{id}/cancel` Cancels a pending invitation so the recipient can no longer accept it. Organization owners and admins may cancel pending invitations. Documentation: https://docs.guidelab.co/api-reference/team/cancelTeamInvitation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Invitation ID ## Responses ### 200: Invitation canceled - `success` (boolean) **(required)**: ### 400: Invitation is not in pending status ### 401: Unauthorized — valid session required ### 403: Forbidden — organization manager required ### 404: Invitation not found in this organization ## Example ```bash curl -X POST "https://api.guidelab.co/team/invitations/{id}/cancel" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Resend a pending invitation `POST https://api.guidelab.co/team/invitations/{id}/resend` Re-sends a pending invitation. An invitation that has already expired is recreated with a new link, so the previously emailed link stays invalid. Only owners may resend co-owner invitations; owners and admins may resend other assignable roles. Documentation: https://docs.guidelab.co/api-reference/team/resendTeamInvitation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Invitation ID ## Responses ### 200: Invitation email resent - `success` (boolean) **(required)**: - `invitation` (object): ### 400: Invitation is not in pending status, or the invitee is already a member ### 401: Unauthorized — valid session required ### 403: Forbidden — organization manager required ### 404: Invitation not found in this organization ### 409: Invitation role is no longer assignable ### 429: Invitation email budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/team/invitations/{id}/resend" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update current user phone number `PUT https://api.guidelab.co/user/phone` Updates the authenticated user's phone number. Validates and stores in E.164 format. Pass an empty string to remove. Documentation: https://docs.guidelab.co/api-reference/users/updateUserPhone ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `phoneNumber` (string) **(required)**: ## Responses ### 200: Phone number updated successfully - `success` (boolean) **(required)**: ### 400: Invalid phone number format ### 401: Unauthorized — valid session required ## Example ```bash curl -X PUT "https://api.guidelab.co/user/phone" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "phoneNumber": "string" }' ``` --- # Update current user language preference `PUT https://api.guidelab.co/user/language` Sets the authenticated user's preferred UI language. Supported: en, es, it, zh. Documentation: https://docs.guidelab.co/api-reference/users/updateUserLanguage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `language` (string) **(required)**: Values: `en`, `es`, `it`, `zh` ## Responses ### 200: Language preference updated - `success` (boolean) **(required)**: ### 400: Invalid language code ### 401: Unauthorized — valid session required ## Example ```bash curl -X PUT "https://api.guidelab.co/user/language" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "language": "en" }' ``` --- # Serve a user avatar `GET https://api.guidelab.co/user/avatar` Serve a user's avatar image from R2 storage. Defaults to the authenticated user. Accessible by self, members of shared organizations, and users in partnership-linked organizations. Documentation: https://docs.guidelab.co/api-reference/users/getUserAvatar ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `userId` (string) (in: query): ## Responses ### 200: Avatar image binary ### 403: Not allowed to view this avatar ### 404: User or avatar not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/user/avatar" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload a user avatar `POST https://api.guidelab.co/user/avatar` Upload a new avatar image. Defaults to the authenticated user; organization owners and admins may pass `userId` for a non-owner member of the active organization. Replaces any existing avatar. Accepts JPEG, PNG, WebP, or GIF up to 5MB. Documentation: https://docs.guidelab.co/api-reference/users/uploadUserAvatar ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `userId` (string) (in: query): ## Responses ### 200: Avatar uploaded successfully - `image` (string) **(required)**: ### 400: Invalid file type or file too large ### 401: Unauthorized — valid session required ### 403: Forbidden — organization manager required ### 404: Member not found in this organization ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/user/avatar" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Remove a user avatar `DELETE https://api.guidelab.co/user/avatar` Remove an avatar from storage and clear the image reference on the user record. Defaults to the authenticated user; organization owners and admins may pass `userId` for a non-owner member of the active organization. Documentation: https://docs.guidelab.co/api-reference/users/deleteUserAvatar ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `userId` (string) (in: query): ## Responses ### 200: Avatar removed successfully - `success` (boolean) **(required)**: ### 400: No avatar to delete ### 401: Unauthorized — valid session required ### 403: Forbidden — organization manager required ### 404: Member not found in this organization ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/user/avatar" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get notification preferences `GET https://api.guidelab.co/user/notification-preferences` Returns notification preferences for all categories and WhatsApp delivery readiness. Missing choices use defaults; saved choices are preserved. Documentation: https://docs.guidelab.co/api-reference/users/getUserNotificationPreferences ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Notification preferences object - `preferences` (object) **(required)**: - `orders` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `events` (object): - `order.status_changed` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `order.assigned` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `order.task_assigned` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `order.phase_advance_requested` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `order.files_reminder` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `order.due_soon` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `order.overdue` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `partnerships` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `chat` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `finance` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `team` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `inventory` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `compliance` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `whatsapp` (object): - `hasPhoneNumber` (boolean) **(required)**: - `configured` (boolean) **(required)**: ### 401: Unauthorized — valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/user/notification-preferences" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update notification preferences `PUT https://api.guidelab.co/user/notification-preferences` Updates the supplied notification categories, preserving omitted categories and order event overrides. Supports email, SMS, WhatsApp, and push channels. Documentation: https://docs.guidelab.co/api-reference/users/updateUserNotificationPreferences ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `preferences` (object) **(required)**: - `orders` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `events` (object): - `order.status_changed` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `order.assigned` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `order.task_assigned` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `order.phase_advance_requested` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `order.files_reminder` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `order.due_soon` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `order.overdue` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `partnerships` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `chat` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `finance` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `team` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `inventory` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: - `compliance` (object): - `email` (boolean) **(required)**: - `sms` (boolean) **(required)**: - `whatsapp` (boolean) **(required)**: - `push` (boolean) **(required)**: ## Responses ### 200: Preferences saved successfully - `success` (boolean) **(required)**: ### 400: Invalid preferences structure ### 401: Unauthorized — valid session required ## Example ```bash curl -X PUT "https://api.guidelab.co/user/notification-preferences" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "preferences": {} }' ``` --- # List all users `GET https://api.guidelab.co/admin/users` Retrieve a paginated list of all platform users with their organization memberships. Platform admin access required. Supports search by email and role filtering. Documentation: https://docs.guidelab.co/api-reference/admin/adminListUsers ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `limit` (string) (in: query): - `offset` (string) (in: query): - `search` (string) (in: query): - `role` (string) (in: query): - `sortDirection` (string) (in: query): ## Responses ### 200: Paginated list of users with organization memberships - `users` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `email` (string) **(required)**: - `image` (string,null) **(required)**: - `role` (string) **(required)**: - `banned` (boolean,null) **(required)**: - `createdAt` (object): - `organizations` (array) **(required)**: - `total` (number) **(required)**: ### 401: Unauthorized ### 403: Forbidden - platform admin only ## Example ```bash curl -X GET "https://api.guidelab.co/admin/users" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get user by ID `GET https://api.guidelab.co/admin/users/{id}` Retrieve a single user's full details including all organization memberships. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminGetUser ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: User details with memberships - `user` (object): - `memberships` (array) **(required)**: ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: User not found ### 409: Organization ownership must be transferred first ## Example ```bash curl -X GET "https://api.guidelab.co/admin/users/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Send password reset email for a user `POST https://api.guidelab.co/admin/users/{id}/send-password-reset` Trigger a password reset email for a specific user via Better Auth's forget-password flow. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminSendPasswordReset ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Password reset email sent - `success` (boolean) **(required)**: ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: User not found ### 409: Organization ownership must be transferred first ## Example ```bash curl -X POST "https://api.guidelab.co/admin/users/{id}/send-password-reset" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Anonymize (GDPR-erase) a user `POST https://api.guidelab.co/admin/users/{id}/anonymize` Scrub a user's PII and revoke all access while retaining their records — orders, invoices, files, and messages reference the user and cannot be deleted. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminAnonymizeUser ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: User anonymized - `success` (boolean) **(required)**: ### 400: Invalid request ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: User not found ## Example ```bash curl -X POST "https://api.guidelab.co/admin/users/{id}/anonymize" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Reset a user's two-factor authentication `POST https://api.guidelab.co/admin/users/{id}/reset-two-factor` Turn off two-factor authentication for a user who has lost both their authenticator and their backup codes, deleting the TOTP secret and backup codes. The user can then sign in with their password and set up two-factor again. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminResetUserTwoFactor ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Two-factor authentication reset - `success` (boolean) **(required)**: ### 400: Invalid request ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: User not found ## Example ```bash curl -X POST "https://api.guidelab.co/admin/users/{id}/reset-two-factor" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List all organizations `GET https://api.guidelab.co/admin/organizations` Retrieve a paginated list of all organizations with member counts. Platform admin access required. Supports search and type filtering. Documentation: https://docs.guidelab.co/api-reference/admin/adminListOrganizations ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (string) (in: query): - `limit` (string) (in: query): - `search` (string) (in: query): - `type` (string) (in: query): ## Responses ### 200: Paginated list of organizations with member counts - `organizations` (array) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 401: Unauthorized ### 403: Forbidden - platform admin only ## Example ```bash curl -X GET "https://api.guidelab.co/admin/organizations" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get organization by ID `GET https://api.guidelab.co/admin/organizations/{id}` Retrieve a single organization's full details including all members and subscription info. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminGetOrganization ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Organization details with members and subscription - `organization` (object): - `members` (array) **(required)**: - `subscription` (object,null) **(required)**: - `id` (string) **(required)**: - `plan` (string) **(required)**: - `status` (string,null) **(required)**: - `periodStart` (string,null) **(required)**: - `periodEnd` (string,null) **(required)**: - `cancelAtPeriodEnd` (boolean,null) **(required)**: - `seats` (number,null) **(required)**: - `trialStart` (string,null) **(required)**: - `trialEnd` (string,null) **(required)**: - `hasBillingCustomer` (boolean) **(required)**: - `complimentary` (boolean) **(required)**: ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Organization not found ## Example ```bash curl -X GET "https://api.guidelab.co/admin/organizations/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update an organization `PUT https://api.guidelab.co/admin/organizations/{id}` Update organization fields (name, slug, type, contact info, etc.). Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminUpdateOrganization ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `name` (string): - `slug` (string): - `city` (string,null): - `email` (string,null): [email] - `phone` (string,null): - `address` (string,null): - `addressLine2` (string,null): - `postcode` (string,null): - `country` (string): - `state` (string,null): - `website` (string,null): [uri] - `companyNumber` (object): - `taxRegistrationNumber` (string,null): - `eInvoiceCode` (object): - `certifiedEmail` (object): - `billingEmail` (string,null): [email] - `standaloneStorageLimitBytes` (integer,null): ## Responses ### 200: Updated organization - `organization` (object): ### 400: No valid fields to update ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Organization not found ### 409: Organization identity conflict ## Example ```bash curl -X PUT "https://api.guidelab.co/admin/organizations/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Create organization subscription checkout session `POST https://api.guidelab.co/admin/organizations/{id}/subscription/checkout` Create a Stripe Checkout session for a lab organization's subscription. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminCreateOrganizationSubscriptionCheckout ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `plan` (string) **(required)**: Values: `base`, `growth`, `scale` - `annual` (boolean): - `returnUrl` (string): [uri] ## Responses ### 200: Checkout session URL - `url` (string) **(required)**: [uri] ### 400: Invalid request or unsupported organization ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Organization not found ### 409: Checkout is already in progress or completed ### 502: Stripe returned an invalid response ### 503: Stripe Checkout is temporarily unavailable ## Example ```bash curl -X POST "https://api.guidelab.co/admin/organizations/{id}/subscription/checkout" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "plan": "base", "annual": true, "returnUrl": "https://example.com" }' ``` --- # Grant a complimentary (free) plan `POST https://api.guidelab.co/admin/organizations/{id}/subscription/complimentary` Put a lab organization on a plan without Stripe billing. Completes onboarding when the lab is on the plan step. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminGrantComplimentaryPlan ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `plan` (string) **(required)**: Values: `base`, `growth`, `scale` ## Responses ### 200: Complimentary plan granted - `subscriptionId` (string) **(required)**: ### 400: Unsupported organization ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Organization not found ### 409: A live subscription, an open checkout, or unfinished onboarding blocks the grant ### 503: Stripe is temporarily unavailable ## Example ```bash curl -X POST "https://api.guidelab.co/admin/organizations/{id}/subscription/complimentary" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "plan": "base" }' ``` --- # Revoke a complimentary (free) plan `DELETE https://api.guidelab.co/admin/organizations/{id}/subscription/complimentary` End a lab organization's free plan immediately. The lab loses write access until it completes a paid subscription. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminRevokeComplimentaryPlan ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Complimentary plan revoked - `subscriptionId` (string) **(required)**: ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Organization not found ### 409: The organization is not on a complimentary plan ## Example ```bash curl -X DELETE "https://api.guidelab.co/admin/organizations/{id}/subscription/complimentary" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create organization billing portal session `POST https://api.guidelab.co/admin/organizations/{id}/subscription/billing-portal` Create a Stripe billing portal session for a lab organization's subscription. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminCreateOrganizationBillingPortal ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `returnUrl` (string): [uri] ## Responses ### 200: Billing portal URL - `url` (string) **(required)**: [uri] ### 400: Invalid request or unsupported organization ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Organization or billing customer not found ## Example ```bash curl -X POST "https://api.guidelab.co/admin/organizations/{id}/subscription/billing-portal" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "returnUrl": "https://example.com" }' ``` --- # Audit Stripe subscriptions GuideLab does not track `GET https://api.guidelab.co/admin/organizations/{id}/subscription/provider-audit` Reports live Stripe subscriptions for a lab organization's customer that have no local subscription row. Bounded to one indexed customer lookup and one subscription page. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminAuditOrganizationProviderSubscriptions ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Untracked provider subscriptions - `stripeCustomerId` (string,null) **(required)**: - `truncated` (boolean) **(required)**: - `untracked` (object[]) **(required)**: - `stripeSubscriptionId` (string) **(required)**: - `status` (string) **(required)**: - `plan` (string,null) **(required)**: - `billingInterval` (string,null) **(required)**: - `billingCurrency` (string,null) **(required)**: - `trialEnd` (string,null) **(required)**: - `currentPeriodEnd` (string,null) **(required)**: - `adoptable` (boolean) **(required)**: ### 400: Unsupported organization ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Organization not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/admin/organizations/{id}/subscription/provider-audit" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Adopt an untracked Stripe subscription `POST https://api.guidelab.co/admin/organizations/{id}/subscription/provider-audit/adopt` Publishes an untracked Stripe subscription as the lab organization's local subscription row so the duplicate-billing guards can see it. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminAdoptUntrackedProviderSubscription ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `stripeSubscriptionId` (string) **(required)**: ## Responses ### 200: Adopted subscription - `subscriptionId` (string) **(required)**: ### 400: Unsupported organization ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Organization or untracked subscription not found ### 409: The subscription cannot be modelled by GuideLab ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/admin/organizations/{id}/subscription/provider-audit/adopt" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "stripeSubscriptionId": "string" }' ``` --- # List duplicate subscription compensations `GET https://api.guidelab.co/admin/subscription-quarantines` List recent unexpected Stripe Checkout completions and their cancellation/refund state. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminListSubscriptionQuarantines ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Subscription quarantine records - `quarantines` (object[]) **(required)**: - `eventId` (string) **(required)**: - `organizationId` (string) **(required)**: - `stripeCheckoutSessionId` (string) **(required)**: - `stripeSubscriptionId` (string) **(required)**: - `stripeInvoiceId` (string,null) **(required)**: - `status` (string) **(required)**: Values: `pending`, `refunded`, `no_payment`, `needs_review` - `refundIds` (string[]) **(required)**: - `errorCode` (string,null) **(required)**: - `notifiedAt` (string,null) **(required)**: [date-time] - `resolvedAt` (string,null) **(required)**: [date-time] - `createdAt` (string) **(required)**: [date-time] - `updatedAt` (string) **(required)**: [date-time] ### 401: Unauthorized ### 403: Forbidden - platform admin only ## Example ```bash curl -X GET "https://api.guidelab.co/admin/subscription-quarantines" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Retry duplicate subscription compensation `POST https://api.guidelab.co/admin/subscription-quarantines/{eventId}/retry` Retry the idempotent cancellation/refund workflow for an unexpected Stripe Checkout completion. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminRetrySubscriptionQuarantine ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `eventId` (string) **(required)** (in: path): ## Responses ### 200: Updated subscription quarantine - `quarantine` (object) **(required)**: - `eventId` (string) **(required)**: - `organizationId` (string) **(required)**: - `stripeCheckoutSessionId` (string) **(required)**: - `stripeSubscriptionId` (string) **(required)**: - `stripeInvoiceId` (string,null) **(required)**: - `status` (string) **(required)**: Values: `pending`, `refunded`, `no_payment`, `needs_review` - `refundIds` (string[]) **(required)**: - `errorCode` (string,null) **(required)**: - `notifiedAt` (string,null) **(required)**: [date-time] - `resolvedAt` (string,null) **(required)**: [date-time] - `createdAt` (string) **(required)**: [date-time] - `updatedAt` (string) **(required)**: [date-time] ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Quarantine record not found ### 503: Stripe compensation is temporarily unavailable ## Example ```bash curl -X POST "https://api.guidelab.co/admin/subscription-quarantines/{eventId}/retry" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Remove a member from an organization `DELETE https://api.guidelab.co/admin/organizations/{id}/members/{memberId}` Remove a member from an organization by member ID. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminRemoveOrganizationMember ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `memberId` (string) **(required)** (in: path): ## Responses ### 200: Member removed successfully - `success` (boolean) **(required)**: ### 400: Missing required IDs ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Member not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/admin/organizations/{id}/members/{memberId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Set admin viewing organization `POST https://api.guidelab.co/admin/set-viewing-org` Set a cookie to impersonate/view a specific organization's data. Used by platform admins to inspect organization dashboards. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminSetViewingOrg ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `organizationId` (string) **(required)**: ## Responses ### 200: Viewing organization cookie set - `success` (boolean) **(required)**: - `organizationType` (string,null) **(required)**: ### 400: organizationId is required ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Organization not found ## Example ```bash curl -X POST "https://api.guidelab.co/admin/set-viewing-org" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "organizationId": "string" }' ``` --- # Clear admin viewing organization `DELETE https://api.guidelab.co/admin/set-viewing-org` Remove the admin viewing organization cookie, returning to the admin's own context. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminClearViewingOrg ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Viewing organization cookie cleared - `success` (boolean) **(required)**: ### 401: Unauthorized ### 403: Forbidden - platform admin only ## Example ```bash curl -X DELETE "https://api.guidelab.co/admin/set-viewing-org" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Preview a notification template `POST https://api.guidelab.co/admin/notifications/preview` Preview how a notification will render across channels (email, SMS, WhatsApp). Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminPreviewNotification ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `eventType` (string) **(required)**: Values: `order.status_changed`, `order.assigned`, `order.task_assigned`, `order.message_added`, `order.phase_advance_requested`, `order.created`, `order.due_soon`, `order.overdue`, `order.files_reminder`, `order.hold_created`, `order.hold_file_submitted`, `order.hold_requirement_approved`, `order.hold_requirement_rejected`, `order.hold_resolved`, `order.surgical_report_sent`, `order.surgical_report_approved`, `order.surgical_report_changes_requested`, `order.cad_approval_sent`, `order.cad_approval_approved`, `order.cad_approval_changes_requested`, `order.issue_reported`, `order.issue_closed`, `partnership.requested`, `partnership.accepted`, `partnership.rejected`, `partnership.suspended`, `partnership.reactivated`, `partnership.terminated`, `invoice.sent`, `invoice.overdue`, `payment.received`, `payment.failed`, `payment.reconciliation_required`, `finance.late_fee_currency_unconfigured`, `org.join_request`, `org.join_request_approved`, `org.join_request_rejected`, `org.member_joined_via_code`, `inventory.low_stock`, `compliance.digest`, `team_chat.message_added` - `channel` (string) **(required)**: Values: `email`, `sms`, `whatsapp` - `data` (object) **(required)**: - `title` (string) **(required)**: - `body` (string) **(required)**: - `entityUrl` (string): - `orderId` (string): - `orderNumber` (string): ## Responses ### 200: Rendered notification preview - `subject` (string): - `html` (string): - `text` (string): - `charCount` (integer): ### 400: Invalid request body ### 401: Unauthorized ### 403: Forbidden - platform admin only ## Example ```bash curl -X POST "https://api.guidelab.co/admin/notifications/preview" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "eventType": "order.status_changed", "channel": "email", "data": { "title": "string", "body": "string", "entityUrl": "string", "orderId": "string", "orderNumber": "string" } }' ``` --- # Send a test notification `POST https://api.guidelab.co/admin/notifications/test` Send a test notification through the selected delivery channel. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminTestNotification ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `eventType` (string) **(required)**: Values: `order.status_changed`, `order.assigned`, `order.task_assigned`, `order.message_added`, `order.phase_advance_requested`, `order.created`, `order.due_soon`, `order.overdue`, `order.files_reminder`, `order.hold_created`, `order.hold_file_submitted`, `order.hold_requirement_approved`, `order.hold_requirement_rejected`, `order.hold_resolved`, `order.surgical_report_sent`, `order.surgical_report_approved`, `order.surgical_report_changes_requested`, `order.cad_approval_sent`, `order.cad_approval_approved`, `order.cad_approval_changes_requested`, `order.issue_reported`, `order.issue_closed`, `partnership.requested`, `partnership.accepted`, `partnership.rejected`, `partnership.suspended`, `partnership.reactivated`, `partnership.terminated`, `invoice.sent`, `invoice.overdue`, `payment.received`, `payment.failed`, `payment.reconciliation_required`, `finance.late_fee_currency_unconfigured`, `org.join_request`, `org.join_request_approved`, `org.join_request_rejected`, `org.member_joined_via_code`, `inventory.low_stock`, `compliance.digest`, `team_chat.message_added` - `channel` (string) **(required)**: Values: `email`, `sms`, `whatsapp` - `data` (object) **(required)**: - `title` (string) **(required)**: - `body` (string) **(required)**: - `entityUrl` (string): - `orderId` (string): - `orderNumber` (string): - `recipient` (string) **(required)**: ## Responses ### 200: Notification accepted for delivery - `success` (boolean) **(required)**: ### 400: Invalid request body ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 429: Paid test-notification rate limit exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/admin/notifications/test" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "eventType": "order.status_changed", "channel": "email", "data": { "title": "string", "body": "string", "entityUrl": "string", "orderId": "string", "orderNumber": "string" }, "recipient": "string" }' ``` --- # Requeue a failed organization closure `POST https://api.guidelab.co/admin/privacy/organization-closures/{organizationId}/requeue` Resets only a terminal failed closure job and writes an attributable intervention receipt. Replays against active or completed jobs are read-only. Documentation: https://docs.guidelab.co/api-reference/admin/adminRequeueOrganizationClosure ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `organizationId` (string) **(required)** (in: path): ## Responses ### 200: Closure requeue result - `status` (string) **(required)**: Values: `requeued`, `already_active`, `completed` ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Closure job not found ### 409: Organization is no longer closing ## Example ```bash curl -X POST "https://api.guidelab.co/admin/privacy/organization-closures/{organizationId}/requeue" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Requeue a failed patient erasure `POST https://api.guidelab.co/admin/privacy/patient-erasures/{patientId}/requeue` Resets only a terminal failed patient-erasure job and writes an attributable intervention receipt. Replays against active or completed jobs are read-only. Documentation: https://docs.guidelab.co/api-reference/admin/adminRequeuePatientErasure ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `patientId` (string) **(required)** (in: path): ## Responses ### 200: Patient-erasure requeue result - `status` (string) **(required)**: Values: `requeued`, `already_active`, `completed` ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Patient-erasure job not found ## Example ```bash curl -X POST "https://api.guidelab.co/admin/privacy/patient-erasures/{patientId}/requeue" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List platform-custody retention holds `GET https://api.guidelab.co/admin/retention-holds` Lists a bounded set of holds transferred to platform legal custody during organization closure. Documentation: https://docs.guidelab.co/api-reference/admin/adminListPlatformCustodyRetentionHolds ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `status` (string) (in: query): Values: `live`, `released`, `all` Default: `live` - `limit` (integer) (in: query): Default: `50` - `holdingOrganizationId` (string) (in: query): ## Responses ### 200: Platform-custody retention holds - `holds` (object[]) **(required)**: - `id` (string) **(required)**: - `holdingOrganizationId` (string) **(required)**: - `matterKey` (string) **(required)**: - `operation` (string) **(required)**: Values: `all`, `identity_erasure`, `object_retirement`, `organization_closure`, `conversation_deletion` - `reason` (string) **(required)**: - `scope` (object) **(required)**: - `kind` (string) **(required)**: Values: `organization`, `partnership`, `patient`, `order`, `invoice`, `statement`, `file`, `conversation`, `conversation_attachment`, `scan_inbox_item` - `id` (string) **(required)**: - `placedAt` (string) **(required)**: [date-time] - `placedBy` (string) **(required)**: - `releasedAt` (string,null) **(required)**: [date-time] - `releasedBy` (string,null) **(required)**: - `reviewDueAt` (string,null) **(required)**: [date-time] - `platformCustodyAt` (string,null) **(required)**: [date-time] ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/admin/retention-holds" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Release a platform-custody retention hold `POST https://api.guidelab.co/admin/retention-holds/{id}/release` Releases a hold after its original organization has closed, preserving the original holder and evidence. Documentation: https://docs.guidelab.co/api-reference/admin/adminReleasePlatformCustodyRetentionHold ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Retention hold released or already released - `status` (string) **(required)**: Values: `released`, `already_released` ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Retention hold not found ### 409: Retention hold is not in platform legal custody ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/admin/retention-holds/{id}/release" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Authorize whole-conversation deletion as platform legal `POST https://api.guidelab.co/admin/conversations/{id}/deletion-override` Authorizes permanent placeholder conversion without participant approvals. Platform admin access and immutable database evidence are required. Documentation: https://docs.guidelab.co/api-reference/admin/adminOverrideConversationDeletion ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 202: Deletion authorized or already authorized - `data` (object) **(required)**: - `conversationId` (string) **(required)**: - `status` (string) **(required)**: Values: `pending`, `authorized`, `completed` - `authorizationKind` (string,null) **(required)**: - `requestedAt` (string) **(required)**: - `authorizedAt` (string,null) **(required)**: - `completedAt` (string,null) **(required)**: - `approvedOrganizationIds` (string[]) **(required)**: ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Conversation not found ### 409: A correlated notification delivery is in flight ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/admin/conversations/{id}/deletion-override" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List platform billing commands requiring or retaining review `GET https://api.guidelab.co/admin/platform-billing-command-reviews` Lists the bounded platform billing review queue and its immutable normalized resolution evidence. Platform admin access required. Documentation: https://docs.guidelab.co/api-reference/admin/adminListPlatformBillingCommandReviews ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `state` (string) (in: query): Values: `unresolved`, `resolved`, `all` Default: `unresolved` - `kind` (string) (in: query): Values: `plan_change`, `storage_add_on` - `cursor` (string) (in: query): - `limit` (integer) (in: query): Default: `50` ## Responses ### 200: Platform billing review queue - `items` (object[]) **(required)**: - `commandId` (string) **(required)**: - `organizationId` (string) **(required)**: - `subscriptionId` (string) **(required)**: - `kind` (string) **(required)**: Values: `plan_change`, `storage_add_on` - `status` (string) **(required)**: - `errorCode` (string,null) **(required)**: - `reviewRequiredAt` (string) **(required)**: [date-time] - `createdAt` (string) **(required)**: [date-time] - `recoveryAttempts` (integer) **(required)**: - `targetPlan` (string,null) **(required)**: Values: `base`, `growth`, `scale`, `null` - `targetBillingInterval` (string,null) **(required)**: Values: `month`, `year`, `null` - `application` (string,null) **(required)**: Values: `immediate`, `scheduled`, `null` - `targetUnits` (integer,null) **(required)**: - `baseUnits` (integer,null) **(required)**: - `billingInterval` (string,null) **(required)**: Values: `month`, `year`, `null` - `change` (string,null) **(required)**: - `resolution` (object,null) **(required)**: - `outcome` (string) **(required)**: Values: `confirmed_provider_target`, `accepted_current_provider_state` - `resultStatus` (string) **(required)**: Values: `completed`, `scheduled`, `failed` - `reviewerUserId` (string) **(required)**: - `reason` (string) **(required)**: - `reviewRequiredAt` (string) **(required)**: [date-time] - `reviewedAt` (string) **(required)**: [date-time] - `sourceErrorCode` (string) **(required)**: - `providerReadAt` (string) **(required)**: [date-time] - `providerSubscriptionStatus` (string) **(required)**: - `providerScheduleId` (string,null) **(required)**: - `activePlan` (string) **(required)**: Values: `base`, `growth`, `scale` - `activeBillingInterval` (string) **(required)**: Values: `month`, `year` - `activeStorageUnits` (integer) **(required)**: - `scheduledPlan` (string,null) **(required)**: Values: `base`, `growth`, `scale`, `null` - `scheduledBillingInterval` (string,null) **(required)**: Values: `month`, `year`, `null` - `scheduledStorageUnits` (integer) **(required)**: - `scheduledAt` (string,null) **(required)**: [date-time] - `nextCursor` (string,null) **(required)**: ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/admin/platform-billing-command-reviews" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Resolve one ambiguous platform billing command `POST https://api.guidelab.co/admin/platform-billing-command-reviews/{commandId}/resolve` Performs at most one Stripe subscription read and one optional schedule read, never writes to Stripe, and closes the command with immutable normalized evidence. Documentation: https://docs.guidelab.co/api-reference/admin/adminResolvePlatformBillingCommandReview ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `commandId` (string) **(required)** (in: path): - `idempotency-key` (string) **(required)** (in: header): Stable key reused only when retrying the exact same command body ## Request Body Content-Type: `application/json` - `outcome` (string) **(required)**: Values: `confirmed_provider_target`, `accepted_current_provider_state` - `reason` (string) **(required)**: ## Responses ### 200: Review resolved or exact resolution replayed - `data` (object) **(required)**: - `commandId` (string) **(required)**: - `organizationId` (string) **(required)**: - `subscriptionId` (string) **(required)**: - `kind` (string) **(required)**: Values: `plan_change`, `storage_add_on` - `status` (string) **(required)**: - `errorCode` (string,null) **(required)**: - `reviewRequiredAt` (string) **(required)**: [date-time] - `createdAt` (string) **(required)**: [date-time] - `recoveryAttempts` (integer) **(required)**: - `targetPlan` (string,null) **(required)**: Values: `base`, `growth`, `scale`, `null` - `targetBillingInterval` (string,null) **(required)**: Values: `month`, `year`, `null` - `application` (string,null) **(required)**: Values: `immediate`, `scheduled`, `null` - `targetUnits` (integer,null) **(required)**: - `baseUnits` (integer,null) **(required)**: - `billingInterval` (string,null) **(required)**: Values: `month`, `year`, `null` - `change` (string,null) **(required)**: - `resolution` (object,null) **(required)**: - `outcome` (string) **(required)**: Values: `confirmed_provider_target`, `accepted_current_provider_state` - `resultStatus` (string) **(required)**: Values: `completed`, `scheduled`, `failed` - `reviewerUserId` (string) **(required)**: - `reason` (string) **(required)**: - `reviewRequiredAt` (string) **(required)**: [date-time] - `reviewedAt` (string) **(required)**: [date-time] - `sourceErrorCode` (string) **(required)**: - `providerReadAt` (string) **(required)**: [date-time] - `providerSubscriptionStatus` (string) **(required)**: - `providerScheduleId` (string,null) **(required)**: - `activePlan` (string) **(required)**: Values: `base`, `growth`, `scale` - `activeBillingInterval` (string) **(required)**: Values: `month`, `year` - `activeStorageUnits` (integer) **(required)**: - `scheduledPlan` (string,null) **(required)**: Values: `base`, `growth`, `scale`, `null` - `scheduledBillingInterval` (string,null) **(required)**: Values: `month`, `year`, `null` - `scheduledStorageUnits` (integer) **(required)**: - `scheduledAt` (string,null) **(required)**: [date-time] - `replayed` (boolean) **(required)**: ### 400: Invalid review request or idempotency header ### 401: Unauthorized ### 403: Forbidden - platform admin only ### 404: Billing review not found ### 409: Review is in progress, already resolved, idempotency-conflicted, or provider state does not satisfy the chosen outcome ### 429: Per-command provider-read budget or backoff reached ### 500: Stripe catalog configuration unavailable ### 503: Provider state could not be read ## Example ```bash curl -X POST "https://api.guidelab.co/admin/platform-billing-command-reviews/{commandId}/resolve" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "outcome": "confirmed_provider_target", "reason": "string" }' ``` --- # List conversations `GET https://api.guidelab.co/conversations` Retrieve paginated conversations for the current organization. Supports filtering by all/unread/waiting/responded and text search across partner names and message previews. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/conversations/listConversations ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `filter` (string) (in: query): Values: `all`, `unread`, `waiting`, `responded` - `search` (string) (in: query): - `limit` (string) (in: query): - `offset` (string) (in: query): - `status` (string) (in: query): Lab only. Effective triage status; an expired snooze is open. Values: `open`, `snoozed`, `closed` - `assignee` (string) (in: query): Lab only. "me", "unassigned", or a lab member id. - `channel` (string) (in: query): Lab only. Threads with a message on this channel. Values: `whatsapp`, `sms`, `telegram`, `messenger`, `instagram`, `email` ## Responses ### 200: Paginated list of conversations with unread counts - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `partnershipId` (string) **(required)**: - `orderId` (string,null) **(required)**: - `title` (string,null) **(required)**: - `lastMessageId` (string,null) **(required)**: - `lastMessageAt` (string,null) **(required)**: - `lastMessagePreview` (string,null) **(required)**: - `lastMessageSenderId` (string,null) **(required)**: - `unreadCounts` (object,null) **(required)**: - `isMuted` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `partner` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `nameMissing` (boolean) **(required)**: - `logo` (string,null) **(required)**: - `order` (object,null) **(required)**: - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `status` (string) **(required)**: - `patientId` (string,null) **(required)**: - `hidePatientFromLab` (boolean) **(required)**: - `patient` (object,null) **(required)**: - `id` (string) **(required)**: - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: - `patientCode` (string,null) **(required)**: - `lastMessageSender` (object,null) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `image` (string,null) **(required)**: - `channels` (string[]) **(required)**: - `lab` (object): - `status` (string) **(required)**: Values: `open`, `snoozed`, `closed` - `snoozedUntil` (string,null) **(required)**: - `assigneeMemberId` (string,null) **(required)**: - `assigneeName` (string,null) **(required)**: - `markedUnread` (boolean) **(required)**: - `totalUnread` (number) **(required)**: - `unsortedCount` (number): Lab only. Open, unread Unsorted senders. - `pagination` (object) **(required)**: - `total` (number) **(required)**: - `limit` (number) **(required)**: - `offset` (number) **(required)**: - `hasMore` (boolean) **(required)**: ### 400: Invalid query parameters ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/conversations" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a conversation `POST https://api.guidelab.co/conversations` Create a new conversation within a partnership. Optionally link it to an order and include an initial message. If a conversation already exists for the same partnership+order, returns the existing one. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/conversations/createConversation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `partnershipId` (string) **(required)**: - `orderId` (string): - `title` (string): - `initialMessage` (string): - `initialMessageId` (string): [uuid] ## Responses ### 200: Existing conversation returned - `data` (object) **(required)**: - `id` (string) **(required)**: - `partnershipId` (string) **(required)**: - `orderId` (string,null) **(required)**: - `title` (string,null) **(required)**: - `lastMessageId` (string,null) **(required)**: - `lastMessageAt` (string,null) **(required)**: - `lastMessagePreview` (string,null) **(required)**: - `lastMessageSenderId` (string,null) **(required)**: - `unreadCounts` (object,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `existing` (boolean) **(required)**: ### 201: Conversation created - `data` (object) **(required)**: - `id` (string) **(required)**: - `partnershipId` (string) **(required)**: - `orderId` (string,null) **(required)**: - `title` (string,null) **(required)**: - `lastMessageId` (string,null) **(required)**: - `lastMessageAt` (string,null) **(required)**: - `lastMessagePreview` (string,null) **(required)**: - `lastMessageSenderId` (string,null) **(required)**: - `unreadCounts` (object,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `existing` (boolean) **(required)**: ### 400: Invalid request body ### 401: Unauthorized ### 403: Not authorized for this partnership ### 404: Partnership not found ### 409: Conversation or initial-message idempotency conflict ## Example ```bash curl -X POST "https://api.guidelab.co/conversations" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "partnershipId": "string", "orderId": "string", "title": "string", "initialMessage": "string", "initialMessageId": "string" }' ``` --- # Get conversation by ID `GET https://api.guidelab.co/conversations/{id}` Retrieve a single conversation with its partner organization, linked order, and last message sender details. Only accessible by organizations that are part of the conversation's partnership. Documentation: https://docs.guidelab.co/api-reference/conversations/getConversation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Conversation details with partner and order info - `data` (object) **(required)**: - `id` (string) **(required)**: - `partnershipId` (string) **(required)**: - `orderId` (string,null) **(required)**: - `title` (string,null) **(required)**: - `lastMessageId` (string,null) **(required)**: - `lastMessageAt` (string,null) **(required)**: - `lastMessagePreview` (string,null) **(required)**: - `lastMessageSenderId` (string,null) **(required)**: - `unreadCounts` (object,null) **(required)**: - `isMuted` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `partner` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `nameMissing` (boolean) **(required)**: - `logo` (string,null) **(required)**: - `order` (object,null) **(required)**: - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `status` (string) **(required)**: - `patient` (object,null) **(required)**: - `id` (string) **(required)**: - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: - `lastMessageSender` (object,null) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `image` (string,null) **(required)**: - `draftContext` (object,null) **(required)**: - `clinicName` (string) **(required)**: - `clinicNameMissing` (boolean) **(required)**: - `doctorName` (string,null) **(required)**: - `patientInitials` (string) **(required)**: - `targetDeliveryDate` (string,null) **(required)**: - `items` (object[]) **(required)**: - `id` (string) **(required)**: - `productName` (string) **(required)**: - `materialName` (string,null) **(required)**: - `quantity` (number) **(required)**: - `teethCount` (number) **(required)**: ### 401: Unauthorized ### 403: Not authorized for this conversation ### 404: Conversation not found ## Example ```bash curl -X GET "https://api.guidelab.co/conversations/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List messages in a conversation `GET https://api.guidelab.co/conversations/{id}/messages` Retrieve paginated messages for a conversation with sender info, org details, and attachments. Internal notes are only visible to the org that sent them. Supports cursor-based pagination via before/after message IDs. Documentation: https://docs.guidelab.co/api-reference/conversations/listConversationMessages ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `limit` (string) (in: query): - `before` (string) (in: query): - `after` (string) (in: query): - `search` (string) (in: query): Case-insensitive substring filter on message content, 2-100 characters. Honours the same internal-note visibility rule as an unfiltered listing. ## Responses ### 200: Paginated list of messages with sender and attachment details - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `conversationId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `orderId` (string,null) **(required)**: - `senderUserId` (string,null) **(required)**: - `senderOrgId` (string) **(required)**: - `origin` (string) **(required)**: Values: `app`, `channel` - `content` (string) **(required)**: - `messageType` (string) **(required)**: - `sequence` (number) **(required)**: - `isInternal` (boolean) **(required)**: - `replyToId` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `sender` (object,null) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `nameMissing` (boolean) **(required)**: - `image` (string,null) **(required)**: - `senderOrg` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `nameMissing` (boolean) **(required)**: - `organizationType` (string) **(required)**: - `attachments` (object[]) **(required)**: - `id` (string) **(required)**: - `messageId` (string) **(required)**: - `name` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (number) **(required)**: - `duration` (number,null) **(required)**: - `hasThumbnail` (boolean) **(required)**: - `transcript` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `replyTo` (object): - `channel` (object): Transport details (MessageChannelInfo) of a channel message; lab-only fields are null for clinics. - `readState` (object) **(required)**: - `partnerOrganizationId` (string) **(required)**: - `partnerLastReadSequence` (number) **(required)**: - `aiAssistanceEnabled` (boolean) **(required)**: - `channels` (object): Lab only. Reply endpoints (ConversationChannels) and the channel the clinic last wrote on. - `pagination` (object) **(required)**: - `hasMore` (boolean) **(required)**: - `oldestId` (string): - `newestId` (string): ### 400: Invalid query parameters ### 401: Unauthorized ### 403: Not authorized for this conversation ### 404: Conversation not found ## Example ```bash curl -X GET "https://api.guidelab.co/conversations/{id}/messages" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Send a message in a conversation `POST https://api.guidelab.co/conversations/{id}/messages` Send a text, image, voice, or file message in a conversation. The client-generated message ID makes exact retries idempotent within the conversation and sender scope. Supports attachments, internal notes (visible only to your org), and reply threads. Updates unread counts and broadcasts to connected WebSocket clients. Labs may also deliver the message to one of the thread's reply endpoints (WhatsApp, SMS, Telegram, Messenger, Instagram or email); it is then queued for delivery. Documentation: https://docs.guidelab.co/api-reference/conversations/sendMessage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `clientMessageId` (string) **(required)**: [uuid] - `content` (string): (default: ``) - `messageType` (string): (default: `text`) Values: `text`, `image`, `voice`, `file` - `isInternal` (boolean): (default: `false`) - `replyToId` (string): - `attachments` (object[]): - `attachmentId` (string) **(required)**: - `duration` (integer): - `endpointId` (string): - `emailSubject` (string): - `template` (object): - `templateId` (string) **(required)**: - `variables` (object): (default: `[object Object]`) ## Responses ### 201: Message sent with sender and attachment details - `data` (object) **(required)**: - `id` (string) **(required)**: - `conversationId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `orderId` (string,null) **(required)**: - `senderUserId` (string) **(required)**: - `senderOrgId` (string) **(required)**: - `content` (string) **(required)**: - `messageType` (string) **(required)**: - `isInternal` (boolean) **(required)**: - `replyToId` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `sender` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `nameMissing` (boolean) **(required)**: - `image` (string,null) **(required)**: - `senderOrg` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `nameMissing` (boolean) **(required)**: - `organizationType` (string) **(required)**: - `attachments` (object[]) **(required)**: - `id` (string) **(required)**: - `messageId` (string) **(required)**: - `name` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (number) **(required)**: - `duration` (number,null) **(required)**: - `hasThumbnail` (boolean) **(required)**: - `transcript` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `replyTo` (object): - `channel` (object): ### 400: Invalid request body ### 401: Unauthorized ### 403: Not authorized for this conversation, or ENDPOINT_NOT_IN_THREAD ### 404: Conversation not found ### 409: Client message ID is already in use, or CONNECTION_UNAVAILABLE ### 422: Client message ID was reused with different data, REPLY_WINDOW_CLOSED, ATTACHMENT_NOT_ALLOWED or TEMPLATE_UNAVAILABLE ## Example ```bash curl -X POST "https://api.guidelab.co/conversations/{id}/messages" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "clientMessageId": "string" }' ``` --- # Mark conversation as read `POST https://api.guidelab.co/conversations/{id}/read` Advance the current organization's conversation read cursor to the latest committed message sequence. Broadcasts the organization-wide cursor to connected clients. Documentation: https://docs.guidelab.co/api-reference/conversations/markConversationRead ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Conversation marked as read - `success` (boolean) **(required)**: - `lastReadSequence` (number) **(required)**: ### 401: Unauthorized ### 403: Not authorized for this conversation ### 404: Conversation not found ## Example ```bash curl -X POST "https://api.guidelab.co/conversations/{id}/read" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Assign, snooze, close or mark a thread unread `PATCH https://api.guidelab.co/conversations/{id}/lab-state` Lab only. Updates the lab's private triage state of a thread: the assignee (a lab member, or null), open/closed, a snooze end, or marking it unread. The clinic never sees this state. Documentation: https://docs.guidelab.co/api-reference/conversations/updateConversationLabState ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `assigneeMemberId` (string,null): - `status` (string): Values: `open`, `closed` - `snoozedUntil` (string): [date-time] - `unread` (boolean): Values: `true` ## Responses ### 200: The thread's triage state - `lab` (object) **(required)**: - `status` (string) **(required)**: Values: `open`, `snoozed`, `closed` - `snoozedUntil` (string,null) **(required)**: - `assigneeMemberId` (string,null) **(required)**: - `assigneeName` (string,null) **(required)**: - `markedUnread` (boolean) **(required)**: ### 400: Invalid change ### 401: Unauthorized ### 403: Only labs triage threads ### 404: Conversation not found ## Example ```bash curl -X PATCH "https://api.guidelab.co/conversations/{id}/lab-state" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "assigneeMemberId": "string", "status": "open", "snoozedUntil": "string", "unread": true }' ``` --- # Retry a failed channel delivery `POST https://api.guidelab.co/conversations/{id}/messages/{messageId}/retry` Lab only. Queues one new delivery attempt of a message whose channel delivery failed. A delivery the provider may already have made is never resent. Documentation: https://docs.guidelab.co/api-reference/conversations/retryConversationMessageDelivery ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `messageId` (string) **(required)** (in: path): ## Responses ### 200: The message with its queued delivery - `message` (object): ### 401: Unauthorized ### 403: Only labs retry deliveries ### 404: Message not found ### 409: Not a failed delivery, the thread is closed to writes, CONNECTION_UNAVAILABLE or DELIVERY_UNKNOWN ### 422: REPLY_WINDOW_CLOSED ## Example ```bash curl -X POST "https://api.guidelab.co/conversations/{id}/messages/{messageId}/retry" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Approve whole-conversation deletion `POST https://api.guidelab.co/conversations/{id}/deletion-approval` Records the current participant organization's immutable approval. Deletion is authorized only after both the lab and clinic approve; platform legal has a separate admin override. Documentation: https://docs.guidelab.co/api-reference/conversations/approveConversationDeletion ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 202: Deletion approval recorded or deletion already authorized - `data` (object) **(required)**: - `conversationId` (string) **(required)**: - `status` (string) **(required)**: Values: `pending`, `authorized`, `completed` - `authorizationKind` (string,null) **(required)**: - `requestedAt` (string) **(required)**: - `authorizedAt` (string,null) **(required)**: - `completedAt` (string,null) **(required)**: - `approvedOrganizationIds` (string[]) **(required)**: ### 401: Unauthorized ### 403: Current organization is not a participant ### 404: Conversation not found ### 409: A correlated notification delivery is in flight ## Example ```bash curl -X POST "https://api.guidelab.co/conversations/{id}/deletion-approval" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Archive a participant-owned conversation attachment `DELETE https://api.guidelab.co/conversations/{id}/attachments/{attachmentId}` Immediately replaces an attachment owned by the current participant with a permanent placeholder. Its objects enter the shared hold-aware retirement lifecycle after 90 days. Documentation: https://docs.guidelab.co/api-reference/conversations/archiveConversationAttachment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `attachmentId` (string) **(required)** (in: path): ## Responses ### 200: Attachment archived or already archived - `data` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: Values: `[Attachment archived]` - `mimeType` (string) **(required)**: Values: `application/octet-stream` - `size` (number) **(required)**: Values: `0` - `duration` (null) **(required)**: - `transcript` (null) **(required)**: - `hasThumbnail` (boolean) **(required)**: Values: `false` ### 401: Unauthorized ### 403: Attachment belongs to the other participant ### 404: Conversation attachment not found ### 409: Attachment has not been finalized ## Example ```bash curl -X DELETE "https://api.guidelab.co/conversations/{id}/attachments/{attachmentId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Prepare a direct conversation attachment upload `POST https://api.guidelab.co/conversations/{id}/attachments/presign` Creates one-use, tenant-bound staging keys and exact-size/content-type presigned PUT URLs. Call finalize after both uploads complete. Documentation: https://docs.guidelab.co/api-reference/conversations/presignConversationAttachment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `filename` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (integer) **(required)**: - `thumbnailSize` (integer): ## Responses ### 201: One-use attachment upload claim created - `attachmentId` (string) **(required)**: - `uploadUrl` (string) **(required)**: - `uploadContentType` (string) **(required)**: - `thumbnailUploadUrl` (string,null) **(required)**: - `thumbnailUploadContentType` (string,null) **(required)**: - `name` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (number) **(required)**: - `category` (string) **(required)**: Values: `images`, `voice`, `files` ### 400: Invalid attachment metadata ### 401: Unauthorized ### 403: Not authorized for this conversation ### 404: Conversation not found ### 429: Upload issuance budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/conversations/{id}/attachments/presign" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "filename": "string", "mimeType": "string", "size": 0, "thumbnailSize": 0 }' ``` --- # Finalize a direct conversation attachment upload `POST https://api.guidelab.co/conversations/{id}/attachments/finalize` Documentation: https://docs.guidelab.co/api-reference/conversations/finalizeConversationAttachment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `attachmentId` (string) **(required)**: ## Responses ### 200: Attachment is ready to send ### 400: Uploaded object does not match the claim ### 401: Unauthorized ### 403: Not authorized for this conversation ### 404: Conversation or upload claim not found ### 409: Upload claim cannot currently be finalized ## Example ```bash curl -X POST "https://api.guidelab.co/conversations/{id}/attachments/finalize" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "attachmentId": "string" }' ``` --- # Transcribe a voice attachment `POST https://api.guidelab.co/conversations/{id}/attachments/transcribe` Transcribe an audio attachment using OpenAI Whisper. Requires the organization to have AI assistance enabled, which is where the data-processing consent is recorded. The attachment may be a ready unsent upload claim owned by the current user or an attachment already sent in the conversation. Documentation: https://docs.guidelab.co/api-reference/conversations/transcribeConversationAttachment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `attachmentId` (string) **(required)**: ## Responses ### 200: Transcription result - `transcript` (string) **(required)**: ### 400: Invalid request or attachment is not audio ### 401: Unauthorized ### 403: Not authorized for this conversation, or AI assistance is disabled for the organization ### 404: Conversation or attachment not found ### 409: Attachment transcription is already in progress ### 429: Transcription rate limit exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/conversations/{id}/attachments/transcribe" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "attachmentId": "string" }' ``` --- # Download a conversation attachment `GET https://api.guidelab.co/conversations/attachments/{id}` Stream a conversation attachment file from R2 storage. Supports thumbnail mode via ?thumbnail=true and proxy mode via ?proxy=true. Only accessible by organizations that are part of the conversation's partnership. Documentation: https://docs.guidelab.co/api-reference/conversations/getConversationAttachment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `preview` (string) (in: query): Values: `true`, `false` - `thumbnail` (string) (in: query): Set to 'true' to return thumbnail version - `proxy` (string) (in: query): Set to 'true' to serve inline instead of as download ## Responses ### 200: Attachment file stream ### 401: Unauthorized ### 403: Not authorized ### 404: Attachment or file not found ### 429: Preview byte budget exceeded ## Example ```bash curl -X GET "https://api.guidelab.co/conversations/attachments/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Unsorted senders `GET https://api.guidelab.co/inbox/unsorted` Lab only. External senders with messages not yet tied to a case thread, newest activity first. Filters by effective triage status, assignee, channel, unread and a text search; paginates with the previous page's `nextCursor`. Documentation: https://docs.guidelab.co/api-reference/inbox/listUnsortedSenders ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `status` (string) (in: query): Values: `open`, `snoozed`, `closed` - `assignee` () (in: query): - `channel` (string) (in: query): Values: `whatsapp`, `sms`, `telegram`, `messenger`, `instagram`, `email` - `unread` (string) (in: query): Values: `true`, `false` - `q` (string) (in: query): - `cursor` (string) (in: query): - `limit` (integer) (in: query): ## Responses ### 200: A page of Unsorted senders - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `nextCursor` (string,null) **(required)**: ### 401: Unauthorized ### 403: Only labs have an Unsorted queue ## Example ```bash curl -X GET "https://api.guidelab.co/inbox/unsorted" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get an Unsorted sender `GET https://api.guidelab.co/inbox/endpoints/{id}` Lab only. The sender and its newest Unsorted messages (at most 100, oldest first), including automatic order questions. Pass `before` (a message id) for older ones. Documentation: https://docs.guidelab.co/api-reference/inbox/getUnsortedSender ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `before` (string) (in: query): ## Responses ### 200: The sender and its Unsorted messages - `endpoint` (object) **(required)**: UnsortedEndpointRow - `id` (string) **(required)**: - `messages` (object[]) **(required)**: - `id` (string) **(required)**: - `hasMore` (boolean) **(required)**: ### 401: Unauthorized ### 403: Only labs have an Unsorted queue ### 404: Sender not found ## Example ```bash curl -X GET "https://api.guidelab.co/inbox/endpoints/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Reply to an Unsorted sender `POST https://api.guidelab.co/inbox/endpoints/{id}/messages` Lab only. Queues a text or WhatsApp-template reply on the sender's channel without tying it to a case. The client message id is the reply's id, so an exact retry is idempotent. Documentation: https://docs.guidelab.co/api-reference/inbox/replyToUnsortedSender ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `clientMessageId` (string) **(required)**: [uuid] - `content` (string): (default: ``) - `emailSubject` (string): - `template` (object): - `templateId` (string) **(required)**: - `variables` (object): (default: `[object Object]`) ## Responses ### 201: The queued reply - `message` (object) **(required)**: UnsortedMessage - `id` (string) **(required)**: ### 401: Unauthorized ### 403: Only labs reply from Unsorted ### 404: Sender not found ### 409: Client message ID is already in use, or CONNECTION_UNAVAILABLE ### 422: Client message ID was reused with different data, REPLY_WINDOW_CLOSED or TEMPLATE_UNAVAILABLE ## Example ```bash curl -X POST "https://api.guidelab.co/inbox/endpoints/{id}/messages" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "clientMessageId": "string", "content": "string", "emailSubject": "string", "template": { "templateId": "string", "variables": {} } }' ``` --- # Tie an Unsorted sender to a case `POST https://api.guidelab.co/inbox/endpoints/{id}/tie` Lab only. Moves the sender's Unsorted messages (at most 50 per call; `remaining` reports the rest) into an order's thread, or the customer's general thread, and routes the sender's next messages there for 24 hours. An unmapped sender is mapped to that customer. Documentation: https://docs.guidelab.co/api-reference/inbox/tieUnsortedSender ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` ## Responses ### 200: Committed messages - `conversationId` (string) **(required)**: - `committed` (number) **(required)**: - `remaining` (number) **(required)**: ### 401: Unauthorized ### 403: The order is not one of the sender's customer's ### 404: Sender, order or customer not found ### 409: The partnership or thread no longer accepts messages ## Example ```bash curl -X POST "https://api.guidelab.co/inbox/endpoints/{id}/tie" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '"string"' ``` --- # Map an Unsorted sender to a customer `PUT https://api.guidelab.co/inbox/endpoints/{id}/customer` Lab only. Maps the sender to a partner clinic and optionally one of its members, or unmaps it with `partnershipId: null`. Any remap drops the sender's order routing and pending question. Documentation: https://docs.guidelab.co/api-reference/inbox/mapUnsortedSender ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `partnershipId` (string,null) **(required)**: - `clinicUserId` (string,null): ## Responses ### 200: The mapped sender - `endpoint` (object) **(required)**: UnsortedEndpointRow - `id` (string) **(required)**: ### 401: Unauthorized ### 403: Only labs map senders ### 404: Sender not found ### 422: Not an active partner clinic, or not its member ## Example ```bash curl -X PUT "https://api.guidelab.co/inbox/endpoints/{id}/customer" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "partnershipId": "string", "clinicUserId": "string" }' ``` --- # Assign, snooze, close or mark an Unsorted sender unread `PATCH https://api.guidelab.co/inbox/endpoints/{id}/lab-state` Lab only. Updates the sender's triage state: the assignee (a lab member, or null), open/closed, a snooze end, or marking it unread. Documentation: https://docs.guidelab.co/api-reference/inbox/updateUnsortedSenderLabState ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `assigneeMemberId` (string,null): - `status` (string): Values: `open`, `closed` - `snoozedUntil` (string): [date-time] - `unread` (boolean): Values: `true` ## Responses ### 200: The updated sender - `endpoint` (object) **(required)**: UnsortedEndpointRow - `id` (string) **(required)**: ### 400: Invalid change ### 401: Unauthorized ### 403: Only labs triage senders ### 404: Sender not found ## Example ```bash curl -X PATCH "https://api.guidelab.co/inbox/endpoints/{id}/lab-state" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "assigneeMemberId": "string", "status": "open", "snoozedUntil": "string", "unread": true }' ``` --- # Mark an Unsorted sender read `POST https://api.guidelab.co/inbox/endpoints/{id}/read` Lab only. Clears the sender's unread flag. Idempotent. Documentation: https://docs.guidelab.co/api-reference/inbox/markUnsortedSenderRead ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Marked read - `ok` (boolean) **(required)**: Values: `true` ### 401: Unauthorized ### 403: Only labs have an Unsorted queue ### 404: Sender not found ## Example ```bash curl -X POST "https://api.guidelab.co/inbox/endpoints/{id}/read" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Retry a failed Unsorted reply `POST https://api.guidelab.co/inbox/channel-messages/{id}/retry` Lab only. Queues one new delivery attempt of a failed reply. A delivery the provider may already have made is never resent. Documentation: https://docs.guidelab.co/api-reference/inbox/retryUnsortedReplyDelivery ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: The reply with its queued delivery - `message` (object) **(required)**: UnsortedMessage - `id` (string) **(required)**: ### 401: Unauthorized ### 403: Only labs retry deliveries ### 404: Reply not found ### 409: Not a failed delivery, CONNECTION_UNAVAILABLE or DELIVERY_UNKNOWN ### 422: REPLY_WINDOW_CLOSED ## Example ```bash curl -X POST "https://api.guidelab.co/inbox/channel-messages/{id}/retry" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Download channel media `GET https://api.guidelab.co/inbox/media/{mediaId}` Streams a photo, voice note or file received on an external channel. The lab reads its own media; a clinic reads only media committed into its own conversations. Documentation: https://docs.guidelab.co/api-reference/inbox/getChannelMedia ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `mediaId` (string) **(required)** (in: path): ## Responses ### 200: The media bytes ### 401: Unauthorized ### 404: Media not found ## Example ```bash curl -X GET "https://api.guidelab.co/inbox/media/{mediaId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List team chat threads `GET https://api.guidelab.co/team-chat/threads` Lab only. The caller's staff threads in the active lab, most recent activity first. Direct threads appear once they have a message. Paginate with the previous page's `nextCursor`. Documentation: https://docs.guidelab.co/api-reference/team-chat/listTeamChatThreads ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `cursor` (string) (in: query): - `limit` (integer) (in: query): ## Responses ### 200: A page of threads - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `kind` (string) **(required)**: Values: `dm`, `group` - `title` (string,null) **(required)**: - `memberUserIds` (string[]) **(required)**: - `lastSequence` (integer) **(required)**: - `lastActivityAt` (string) **(required)**: - `lastMessage` (object,null) **(required)**: - `id` (string) **(required)**: - `threadId` (string) **(required)**: - `sequence` (integer) **(required)**: - `senderUserId` (string,null) **(required)**: - `body` (string) **(required)**: - `attachments` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (integer) **(required)**: - `createdAt` (string) **(required)**: - `unreadCount` (integer) **(required)**: - `nextCursor` (string,null) **(required)**: ### 401: Unauthorized ### 403: Only lab members can use team chat, and never while impersonating ## Example ```bash curl -X GET "https://api.guidelab.co/team-chat/threads" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Open a direct thread or create a group `POST https://api.guidelab.co/team-chat/threads` Lab only. A direct thread is get-or-create per member pair (201 when created, 200 when it existed) and notifies nobody until its first message. A group includes the caller and notifies its members. Documentation: https://docs.guidelab.co/api-reference/team-chat/createTeamChatThread ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` ## Responses ### 200: The existing direct thread - `thread` (object) **(required)**: - `id` (string) **(required)**: - `kind` (string) **(required)**: Values: `dm`, `group` - `title` (string,null) **(required)**: - `memberUserIds` (string[]) **(required)**: - `lastSequence` (integer) **(required)**: - `lastActivityAt` (string) **(required)**: - `lastMessage` (object,null) **(required)**: - `id` (string) **(required)**: - `threadId` (string) **(required)**: - `sequence` (integer) **(required)**: - `senderUserId` (string,null) **(required)**: - `body` (string) **(required)**: - `attachments` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (integer) **(required)**: - `createdAt` (string) **(required)**: - `unreadCount` (integer) **(required)**: ### 201: The new thread - `thread` (object) **(required)**: - `id` (string) **(required)**: - `kind` (string) **(required)**: Values: `dm`, `group` - `title` (string,null) **(required)**: - `memberUserIds` (string[]) **(required)**: - `lastSequence` (integer) **(required)**: - `lastActivityAt` (string) **(required)**: - `lastMessage` (object,null) **(required)**: - `id` (string) **(required)**: - `threadId` (string) **(required)**: - `sequence` (integer) **(required)**: - `senderUserId` (string,null) **(required)**: - `body` (string) **(required)**: - `attachments` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (integer) **(required)**: - `createdAt` (string) **(required)**: - `unreadCount` (integer) **(required)**: ### 400: Yourself, or someone outside the lab ### 401: Unauthorized ### 403: Only lab members can use team chat, and never while impersonating ## Example ```bash curl -X POST "https://api.guidelab.co/team-chat/threads" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '"string"' ``` --- # Get a team chat thread `GET https://api.guidelab.co/team-chat/threads/{threadId}` Lab only. 404 unless the caller is a member. Documentation: https://docs.guidelab.co/api-reference/team-chat/getTeamChatThread ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `threadId` (string) **(required)** (in: path): ## Responses ### 200: The thread - `thread` (object) **(required)**: - `id` (string) **(required)**: - `kind` (string) **(required)**: Values: `dm`, `group` - `title` (string,null) **(required)**: - `memberUserIds` (string[]) **(required)**: - `lastSequence` (integer) **(required)**: - `lastActivityAt` (string) **(required)**: - `lastMessage` (object,null) **(required)**: - `id` (string) **(required)**: - `threadId` (string) **(required)**: - `sequence` (integer) **(required)**: - `senderUserId` (string,null) **(required)**: - `body` (string) **(required)**: - `attachments` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (integer) **(required)**: - `createdAt` (string) **(required)**: - `unreadCount` (integer) **(required)**: ### 401: Unauthorized ### 403: Only lab members can use team chat, and never while impersonating ### 404: Thread not found ## Example ```bash curl -X GET "https://api.guidelab.co/team-chat/threads/{threadId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List team chat messages `GET https://api.guidelab.co/team-chat/threads/{threadId}/messages` Lab only, members only. Newest first; `nextCursor` is the lowest sequence on the page, and `cursor` returns the messages before it. Documentation: https://docs.guidelab.co/api-reference/team-chat/listTeamChatMessages ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `threadId` (string) **(required)** (in: path): - `cursor` (integer) (in: query): - `limit` (integer) (in: query): ## Responses ### 200: A page of messages, newest first - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `threadId` (string) **(required)**: - `sequence` (integer) **(required)**: - `senderUserId` (string,null) **(required)**: - `body` (string) **(required)**: - `attachments` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (integer) **(required)**: - `createdAt` (string) **(required)**: - `nextCursor` (string,null) **(required)**: ### 401: Unauthorized ### 403: Only lab members can use team chat, and never while impersonating ### 404: Thread not found ## Example ```bash curl -X GET "https://api.guidelab.co/team-chat/threads/{threadId}/messages" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Send a team chat message `POST https://api.guidelab.co/team-chat/threads/{threadId}/messages` Lab only, members only. The message id is `clientMessageId`: a retry returns the stored message with 200 and repeats no side effect. Attachments must be the caller's finalized, unsent uploads to this thread. Members are notified live; members who were caught up also get a content-free push. Documentation: https://docs.guidelab.co/api-reference/team-chat/sendTeamChatMessage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `threadId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `clientMessageId` (string) **(required)**: [uuid] - `body` (string): (default: ``) - `attachmentIds` (string[]): (default: ``) ## Responses ### 200: The stored message (a retry) - `message` (object) **(required)**: - `id` (string) **(required)**: - `threadId` (string) **(required)**: - `sequence` (integer) **(required)**: - `senderUserId` (string,null) **(required)**: - `body` (string) **(required)**: - `attachments` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (integer) **(required)**: - `createdAt` (string) **(required)**: ### 201: The new message - `message` (object) **(required)**: - `id` (string) **(required)**: - `threadId` (string) **(required)**: - `sequence` (integer) **(required)**: - `senderUserId` (string,null) **(required)**: - `body` (string) **(required)**: - `attachments` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (integer) **(required)**: - `createdAt` (string) **(required)**: ### 401: Unauthorized ### 403: Only lab members can use team chat, and never while impersonating ### 404: Thread not found ### 409: `ATTACHMENT_UNAVAILABLE`, or `MESSAGE_ID_CONFLICT` when the id belongs to another message ## Example ```bash curl -X POST "https://api.guidelab.co/team-chat/threads/{threadId}/messages" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "clientMessageId": "string", "body": "string", "attachmentIds": [ "string" ] }' ``` --- # Mark a team chat thread read `POST https://api.guidelab.co/team-chat/threads/{threadId}/read` Lab only, members only. Moves the caller's read position forward, never back, and never past the last message. Returns it with the caller's unread total across the lab. Documentation: https://docs.guidelab.co/api-reference/team-chat/markTeamChatThreadRead ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `threadId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `upToSequence` (integer) **(required)**: ## Responses ### 200: The read position and unread total - `lastReadSequence` (integer) **(required)**: - `unreadCount` (integer) **(required)**: ### 401: Unauthorized ### 403: Only lab members can use team chat, and never while impersonating ### 404: Thread not found ## Example ```bash curl -X POST "https://api.guidelab.co/team-chat/threads/{threadId}/read" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "upToSequence": 0 }' ``` --- # Add members to a team chat group `POST https://api.guidelab.co/team-chat/threads/{threadId}/members` Lab only, group members only. New members start caught up and see the history. At most 50 members per group. Documentation: https://docs.guidelab.co/api-reference/team-chat/addTeamChatThreadMembers ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `threadId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `userIds` (string[]) **(required)**: ## Responses ### 200: The updated group - `thread` (object) **(required)**: - `id` (string) **(required)**: - `kind` (string) **(required)**: Values: `dm`, `group` - `title` (string,null) **(required)**: - `memberUserIds` (string[]) **(required)**: - `lastSequence` (integer) **(required)**: - `lastActivityAt` (string) **(required)**: - `lastMessage` (object,null) **(required)**: - `id` (string) **(required)**: - `threadId` (string) **(required)**: - `sequence` (integer) **(required)**: - `senderUserId` (string,null) **(required)**: - `body` (string) **(required)**: - `attachments` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (integer) **(required)**: - `createdAt` (string) **(required)**: - `unreadCount` (integer) **(required)**: ### 400: `UNKNOWN_MEMBER`: someone outside the lab ### 401: Unauthorized ### 403: Only lab members can use team chat, and never while impersonating ### 404: Thread not found ### 409: `NOT_GROUP` or `GROUP_FULL` ## Example ```bash curl -X POST "https://api.guidelab.co/team-chat/threads/{threadId}/members" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "userIds": [ "string" ] }' ``` --- # Remove a member from a team chat group `DELETE https://api.guidelab.co/team-chat/threads/{threadId}/members/{userId}` Lab only, group members only. Any member may remove anyone; removing yourself leaves the group, and the response thread is then null. Documentation: https://docs.guidelab.co/api-reference/team-chat/removeTeamChatThreadMember ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `threadId` (string) **(required)** (in: path): - `userId` (string) **(required)** (in: path): ## Responses ### 200: The updated group, or null after leaving it - `thread` (object,null) **(required)**: - `id` (string) **(required)**: - `kind` (string) **(required)**: Values: `dm`, `group` - `title` (string,null) **(required)**: - `memberUserIds` (string[]) **(required)**: - `lastSequence` (integer) **(required)**: - `lastActivityAt` (string) **(required)**: - `lastMessage` (object,null) **(required)**: - `id` (string) **(required)**: - `threadId` (string) **(required)**: - `sequence` (integer) **(required)**: - `senderUserId` (string,null) **(required)**: - `body` (string) **(required)**: - `attachments` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (integer) **(required)**: - `createdAt` (string) **(required)**: - `unreadCount` (integer) **(required)**: ### 400: `UNKNOWN_MEMBER`: not a member of this group ### 401: Unauthorized ### 403: Only lab members can use team chat, and never while impersonating ### 404: Thread not found ### 409: `NOT_GROUP` ## Example ```bash curl -X DELETE "https://api.guidelab.co/team-chat/threads/{threadId}/members/{userId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Prepare a team chat attachment upload `POST https://api.guidelab.co/team-chat/threads/{threadId}/attachments/presign` Lab only, members only. The conversation attachment contract: a one-use staging key and an exact-size, content-type-bound presigned PUT (15 minutes). Team chat makes no thumbnails, so the thumbnail fields are null. Call finalize after the upload. Documentation: https://docs.guidelab.co/api-reference/team-chat/presignTeamChatAttachment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `threadId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `filename` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (integer) **(required)**: - `thumbnailSize` (integer): ## Responses ### 201: One-use attachment upload claim created - `attachmentId` (string) **(required)**: - `uploadUrl` (string) **(required)**: - `uploadContentType` (string) **(required)**: - `thumbnailUploadUrl` (string,null) **(required)**: - `thumbnailUploadContentType` (string,null) **(required)**: - `name` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (number) **(required)**: - `category` (string) **(required)**: Values: `images`, `voice`, `files` ### 400: Unsupported attachment type ### 401: Unauthorized ### 403: Only lab members can use team chat, and never while impersonating ### 404: Thread not found ### 429: Upload issuance budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/team-chat/threads/{threadId}/attachments/presign" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "filename": "string", "mimeType": "string", "size": 0, "thumbnailSize": 0 }' ``` --- # Finalize a team chat attachment upload `POST https://api.guidelab.co/team-chat/threads/{threadId}/attachments/finalize` Lab only, the uploader only. Promotes the staged bytes to their immutable key and records their SHA-256; the attachment is then ready to send. Idempotent: an already finalized upload touches no storage. Documentation: https://docs.guidelab.co/api-reference/team-chat/finalizeTeamChatAttachment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `threadId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `attachmentId` (string) **(required)**: ## Responses ### 200: Attachment is ready to send - `attachmentId` (string) **(required)**: - `status` (string) **(required)**: Values: `ready` ### 400: Uploaded object does not match the claim ### 401: Unauthorized ### 403: Only lab members can use team chat, and never while impersonating ### 404: Upload claim not found ### 409: Upload is missing or its claim has expired ## Example ```bash curl -X POST "https://api.guidelab.co/team-chat/threads/{threadId}/attachments/finalize" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "attachmentId": "string" }' ``` --- # Download a team chat attachment `GET https://api.guidelab.co/team-chat/attachments/{attachmentId}` Lab only, thread members only. Streams a sent attachment. `proxy=true` serves safe types inline; `preview=true` reads are byte-budgeted. Documentation: https://docs.guidelab.co/api-reference/team-chat/getTeamChatAttachment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `attachmentId` (string) **(required)** (in: path): - `preview` (string) (in: query): Values: `true`, `false` - `proxy` (string) (in: query): Values: `true`, `false` ## Responses ### 200: Attachment file stream ### 401: Unauthorized ### 403: Only lab members can use team chat, and never while impersonating ### 404: Attachment not found ### 429: Preview byte budget exceeded ## Example ```bash curl -X GET "https://api.guidelab.co/team-chat/attachments/{attachmentId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Count unread team chat messages `GET https://api.guidelab.co/team-chat/unread` Lab only. The caller's exact unread total across their threads in the active lab. Documentation: https://docs.guidelab.co/api-reference/team-chat/getTeamChatUnreadCount ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: The unread total - `unreadCount` (integer) **(required)**: ### 401: Unauthorized ### 403: Only lab members can use team chat, and never while impersonating ## Example ```bash curl -X GET "https://api.guidelab.co/team-chat/unread" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # One-click unsubscribe from notification emails `POST https://api.guidelab.co/notifications/unsubscribe` Public endpoint used by List-Unsubscribe headers to disable email notifications for a single notification category. Documentation: https://docs.guidelab.co/api-reference/notifications/unsubscribeNotificationEmails ## Parameters - `token` (string) **(required)** (in: query): ## Responses ### 200: Notification email preference updated ### 400: Invalid unsubscribe token ## Example ```bash curl -X POST "https://api.guidelab.co/notifications/unsubscribe" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List notifications `GET https://api.guidelab.co/notifications` Retrieve paginated notifications for the current user within their active organization. Supports cursor-based pagination and filtering by unread status. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/notifications/listNotifications ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `limit` (string) (in: query): Max items to return (1-50, default 20) - `before` (string) (in: query): Cursor: notification ID to paginate before - `unreadOnly` (string) (in: query): Set to 'true' to return only unread notifications ## Responses ### 200: Paginated list of notifications with unread count - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `userId` (string) **(required)**: - `organizationId` (string) **(required)**: - `type` (string) **(required)**: - `title` (string) **(required)**: - `body` (string,null) **(required)**: - `data` (object): - `readAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `unreadCount` (number) **(required)**: - `hasMore` (boolean) **(required)**: ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/notifications" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get conversation unread count `GET https://api.guidelab.co/notifications/count` Returns the total number of unread conversation messages across all partnerships for the current organization. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/notifications/getConversationUnreadCount ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Total unread conversation message count - `unreadCount` (number) **(required)**: ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/notifications/count" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Mark notifications as read `POST https://api.guidelab.co/notifications/mark-read` Mark specific notifications or all unread notifications as read for the current user. Provide either an array of notificationIds or set all to true. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/notifications/markNotificationsRead ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `notificationIds` (string[]): - `all` (boolean): Values: `true` ## Responses ### 200: Notifications marked as read - `success` (boolean) **(required)**: ### 400: Invalid request body ### 401: Unauthorized ## Example ```bash curl -X POST "https://api.guidelab.co/notifications/mark-read" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "notificationIds": [ "string" ], "all": true }' ``` --- # Get notification unread count `GET https://api.guidelab.co/notifications/unread-count` Returns the count of unread notifications for the current user within their active organization. Available to both labs and clinics. Documentation: https://docs.guidelab.co/api-reference/notifications/getNotificationUnreadCount ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Unread notification count - `count` (number) **(required)**: ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/notifications/unread-count" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get VAPID public key `GET https://api.guidelab.co/push-subscriptions/vapid-key` Returns the VAPID public key needed to subscribe to push notifications. Requires user authentication but no specific organization context. Documentation: https://docs.guidelab.co/api-reference/push-subscriptions/getVapidPublicKey ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: VAPID public key for push notification subscription - `publicKey` (string) **(required)**: ### 401: Unauthorized ### 503: Push notifications not configured on the server ## Example ```bash curl -X GET "https://api.guidelab.co/push-subscriptions/vapid-key" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List push subscriptions `GET https://api.guidelab.co/push-subscriptions` List all registered push subscriptions for the current user. Requires user authentication. Documentation: https://docs.guidelab.co/api-reference/push-subscriptions/listPushSubscriptions ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of registered push subscriptions for the current user - `subscriptions` (object[]) **(required)**: - `id` (string) **(required)**: - `endpoint` (string) **(required)**: - `userAgent` (string,null) **(required)**: - `createdAt` (string) **(required)**: ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/push-subscriptions" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Register push subscription `POST https://api.guidelab.co/push-subscriptions` Register a new Web Push subscription for the current user. If the endpoint already exists, it will be updated with the new keys. Requires user authentication. Documentation: https://docs.guidelab.co/api-reference/push-subscriptions/registerPushSubscription ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `endpoint` (string) **(required)**: [uri] - `keys` (object) **(required)**: - `p256dh` (string) **(required)**: - `auth` (string) **(required)**: ## Responses ### 201: Push subscription registered successfully - `success` (boolean) **(required)**: ### 400: Invalid subscription data ### 401: Unauthorized ### 409: Push subscription limit reached ## Example ```bash curl -X POST "https://api.guidelab.co/push-subscriptions" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "endpoint": "https://example.com", "keys": { "p256dh": "string", "auth": "string" } }' ``` --- # Unregister push subscription `DELETE https://api.guidelab.co/push-subscriptions` Remove a push subscription by its endpoint URL. Only subscriptions belonging to the current user will be removed. Requires user authentication. Documentation: https://docs.guidelab.co/api-reference/push-subscriptions/unregisterPushSubscription ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `endpoint` (string) **(required)**: [uri] ## Responses ### 200: Push subscription removed successfully - `success` (boolean) **(required)**: ### 400: Invalid request body ### 401: Unauthorized ## Example ```bash curl -X DELETE "https://api.guidelab.co/push-subscriptions" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "endpoint": "https://example.com" }' ``` --- # Register this device's Expo push token `PUT https://api.guidelab.co/push-subscriptions/native` Binds an Expo push token to the calling device credential. Repeating the current token writes nothing, and a token held by another credential moves here. Signing out, credential expiry, membership removal and password changes end it; there is no separate unregister call. Requires the native device credential. Documentation: https://docs.guidelab.co/api-reference/push-subscriptions/registerNativePushToken ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `token` (string) **(required)**: ## Responses ### 200: Push token registered - `success` (boolean) **(required)**: ### 400: Invalid push token ### 401: Native device credential required ### 409: Push device limit reached ## Example ```bash curl -X PUT "https://api.guidelab.co/push-subscriptions/native" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "token": "string" }' ``` --- # Get Company Settings `GET https://api.guidelab.co/company-settings` Retrieve the company settings for the current organization, including contact details, address, and preferences. Documentation: https://docs.guidelab.co/api-reference/company-settings/getCompanySettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Company settings for the current organization - `settings` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `slug` (string) **(required)**: - `logo` (string,null) **(required)**: - `labReference` (string,null) **(required)**: - `email` (string,null) **(required)**: - `billingEmail` (string,null) **(required)**: - `address` (string,null) **(required)**: - `addressLine2` (string,null) **(required)**: - `city` (string,null) **(required)**: - `state` (string,null) **(required)**: - `country` (string,null) **(required)**: - `postcode` (string,null) **(required)**: - `timezone` (string) **(required)**: - `currency` (string) **(required)**: - `dateFormat` (string,null) **(required)**: - `phone` (string,null) **(required)**: - `website` (string,null) **(required)**: - `companyNumber` (string,null) **(required)**: - `taxRegistrationNumber` (string,null) **(required)**: - `eInvoiceCode` (string,null) **(required)**: - `certifiedEmail` (string,null) **(required)**: - `teethChartingSystem` (string,null) **(required)**: - `aiAssistanceEnabled` (boolean) **(required)**: - `workTypeLayout` (string,null) **(required)**: - `latitude` (string,null) **(required)**: - `longitude` (string,null) **(required)**: - `isDiscoverable` (boolean,null) **(required)**: - `description` (string,null) **(required)**: - `coverImage` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 404: Organization not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/company-settings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Company Settings `PUT https://api.guidelab.co/company-settings` Update company settings such as name, contact information, address, currency, and other organization preferences. Documentation: https://docs.guidelab.co/api-reference/company-settings/updateCompanySettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string): - `labReference` (string,null): - `email` (string,null): [email] - `billingEmail` (string,null): [email] - `address` (string,null): - `addressLine2` (string,null): - `city` (string,null): - `state` (string,null): - `country` (string): - `postcode` (string,null): - `timezone` (string): - `currency` (string): Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `acknowledgeCatalogRepricingRows` (integer): - `dateFormat` (string,null): Values: `DD/MM/YYYY`, `MM/DD/YYYY`, `YYYY-MM-DD`, `DD-MM-YYYY`, `DD.MM.YYYY`, `null` - `phone` (string,null): - `website` (object): - `companyNumber` (object): - `taxRegistrationNumber` (string,null): - `eInvoiceCode` (object): - `certifiedEmail` (object): - `teethChartingSystem` (string,null): Values: `FDI`, `Universal`, `Palmer`, `null` - `aiAssistanceEnabled` (boolean): - `workTypeLayout` (string): Values: `stepper`, `standard` - `latitude` (number,null): - `longitude` (number,null): - `isDiscoverable` (boolean): - `description` (string,null): ## Responses ### 200: Successfully updated company settings - `settings` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `slug` (string) **(required)**: - `logo` (string,null) **(required)**: - `labReference` (string,null) **(required)**: - `email` (string,null) **(required)**: - `billingEmail` (string,null) **(required)**: - `address` (string,null) **(required)**: - `addressLine2` (string,null) **(required)**: - `city` (string,null) **(required)**: - `state` (string,null) **(required)**: - `country` (string,null) **(required)**: - `postcode` (string,null) **(required)**: - `timezone` (string) **(required)**: - `currency` (string) **(required)**: - `dateFormat` (string,null) **(required)**: - `phone` (string,null) **(required)**: - `website` (string,null) **(required)**: - `companyNumber` (string,null) **(required)**: - `taxRegistrationNumber` (string,null) **(required)**: - `eInvoiceCode` (string,null) **(required)**: - `certifiedEmail` (string,null) **(required)**: - `teethChartingSystem` (string,null) **(required)**: - `aiAssistanceEnabled` (boolean) **(required)**: - `workTypeLayout` (string,null) **(required)**: - `latitude` (string,null) **(required)**: - `longitude` (string,null) **(required)**: - `isDiscoverable` (boolean,null) **(required)**: - `description` (string,null) **(required)**: - `coverImage` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 404: Organization not found ### 409: Currency is locked by financial facts, needs a repricing confirmation, conflicts with persisted catalog prices, or the legal identity is already registered - `error` (string) **(required)**: - `code` (string): Values: `currency_locked_by_financial_facts`, `catalog_repricing_confirmation_required`, `catalog_currency_precision_conflict` - `details` (object): ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/company-settings" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Get Company Logo `GET https://api.guidelab.co/company-settings/logo` Serve the company logo image from R2 storage. The optional orgId parameter is limited to the current organization, organizations the caller is a member of, discoverable organizations, or active partners. Pass the organization's logo asset id as v to receive a long-lived immutable response. Documentation: https://docs.guidelab.co/api-reference/company-settings/getCompanyLogo ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `orgId` (string) (in: query): - `v` (string) (in: query): Logo asset id. When it matches the stored logo the response is immutably cacheable; a new logo changes the id and so the URL. ## Responses ### 200: Company logo image binary ### 404: Organization or logo not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/company-settings/logo" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload Company Logo `POST https://api.guidelab.co/company-settings/logo` Upload a new company logo image. Replaces any existing logo. Accepts JPEG, PNG, WebP, or GIF up to 5MB. Documentation: https://docs.guidelab.co/api-reference/company-settings/uploadCompanyLogo ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Successfully uploaded company logo - `settings` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `logo` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid file type or file too large ### 404: Organization not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/company-settings/logo" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Company Logo `DELETE https://api.guidelab.co/company-settings/logo` Remove the company logo from R2 storage and clear the logo reference in the organization record. Documentation: https://docs.guidelab.co/api-reference/company-settings/deleteCompanyLogo ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Company logo successfully removed - `settings` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `logo` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `message` (string) **(required)**: ### 400: No logo to delete ### 404: Organization not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/company-settings/logo" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Company Cover Image `GET https://api.guidelab.co/company-settings/cover-image` Serve the company cover image from R2 storage. The optional orgId parameter is limited to the current organization, organizations the caller is a member of, discoverable organizations, or active partners. Documentation: https://docs.guidelab.co/api-reference/company-settings/getCompanyCoverImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `orgId` (string) (in: query): ## Responses ### 200: Cover image binary ### 404: Organization or cover image not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/company-settings/cover-image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload Company Cover Image `POST https://api.guidelab.co/company-settings/cover-image` Upload a new cover image for the company profile. Replaces any existing cover image. Accepts JPEG, PNG, WebP, or GIF up to 5MB. Documentation: https://docs.guidelab.co/api-reference/company-settings/uploadCompanyCoverImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Cover image successfully uploaded - `success` (boolean) **(required)**: ### 400: Invalid file type or file too large ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/company-settings/cover-image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Company Cover Image `DELETE https://api.guidelab.co/company-settings/cover-image` Remove the company cover image from R2 storage and clear the reference in the organization record. Documentation: https://docs.guidelab.co/api-reference/company-settings/deleteCompanyCoverImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Cover image successfully removed - `success` (boolean) **(required)**: ### 400: No cover image to delete ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/company-settings/cover-image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Company Gallery Images `GET https://api.guidelab.co/company-settings/gallery` List all gallery images for the organization, sorted by display order. The optional orgId parameter is limited to the current organization, organizations the caller is a member of, discoverable organizations, or active partners. Documentation: https://docs.guidelab.co/api-reference/company-settings/listCompanyGalleryImages ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `orgId` (string) (in: query): ## Responses ### 200: List of gallery images with URLs and sort order Array of: - `id` (string) **(required)**: - `url` (string) **(required)**: - `sortOrder` (number) **(required)**: ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/company-settings/gallery" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload Company Gallery Image `POST https://api.guidelab.co/company-settings/gallery` Upload a new gallery image for the company profile. Accepts JPEG, PNG, WebP, or GIF up to 5MB. Automatically assigned the next sort order. Documentation: https://docs.guidelab.co/api-reference/company-settings/uploadCompanyGalleryImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Successfully uploaded gallery image with ID and URL - `id` (string) **(required)**: - `url` (string) **(required)**: - `sortOrder` (number) **(required)**: ### 400: Invalid file type or file too large ### 409: Organization gallery image limit reached ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/company-settings/gallery" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Reorder Company Gallery Images `POST https://api.guidelab.co/company-settings/gallery/reorder` Reorder gallery images by providing an ordered array of image IDs. Each image's sort order is updated to match its position in the array. Documentation: https://docs.guidelab.co/api-reference/company-settings/reorderCompanyGalleryImages ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `ids` (string[]) **(required)**: ## Responses ### 200: Gallery images successfully reordered - `success` (boolean) **(required)**: ### 400: Invalid request body ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/company-settings/gallery/reorder" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "ids": [ "string" ] }' ``` --- # Get Company Gallery Image `GET https://api.guidelab.co/company-settings/gallery/{id}/image` Serve a specific gallery image binary from R2 storage by its ID. Documentation: https://docs.guidelab.co/api-reference/company-settings/getCompanyGalleryImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Gallery image binary ### 404: Gallery image not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/company-settings/gallery/{id}/image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Company Gallery Image `DELETE https://api.guidelab.co/company-settings/gallery/{id}` Delete a specific gallery image from R2 storage and remove its database record. Documentation: https://docs.guidelab.co/api-reference/company-settings/deleteCompanyGalleryImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Gallery image successfully deleted - `success` (boolean) **(required)**: ### 404: Gallery image not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/company-settings/gallery/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Document Settings `GET https://api.guidelab.co/document-settings` Retrieve document settings for the current lab, including title, terms and conditions, footer text, and manufacture details. Documentation: https://docs.guidelab.co/api-reference/document-settings/getDocumentSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Document settings for the current lab - `settings` (object) **(required)**: - `id` (string,null) **(required)**: - `labId` (string) **(required)**: - `documentType` (string) **(required)**: - `title` (string,null) **(required)**: - `termsAndConditions` (string,null) **(required)**: - `footerText` (string,null) **(required)**: - `footerLogoKey` (string,null) **(required)**: - `manufactureTitle` (string,null) **(required)**: - `manufactureText` (string,null) **(required)**: - `showAdditionalProductInfo` (boolean) **(required)**: - `createdAt` (string,null) **(required)**: - `updatedAt` (string,null) **(required)**: ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/document-settings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Document Settings `PUT https://api.guidelab.co/document-settings` Update document settings for the current lab. Creates default settings if none exist. Controls document title, terms, footer text, and manufacture info. Documentation: https://docs.guidelab.co/api-reference/document-settings/updateDocumentSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `title` (string,null): - `termsAndConditions` (string,null): - `footerText` (string,null): - `manufactureTitle` (string,null): - `manufactureText` (string,null): - `showAdditionalProductInfo` (boolean): ## Responses ### 200: Successfully updated document settings - `settings` (object) **(required)**: - `id` (string,null) **(required)**: - `labId` (string) **(required)**: - `documentType` (string) **(required)**: - `title` (string,null) **(required)**: - `termsAndConditions` (string,null) **(required)**: - `footerText` (string,null) **(required)**: - `footerLogoKey` (string,null) **(required)**: - `manufactureTitle` (string,null) **(required)**: - `manufactureText` (string,null) **(required)**: - `showAdditionalProductInfo` (boolean) **(required)**: - `createdAt` (string,null) **(required)**: - `updatedAt` (string,null) **(required)**: ### 400: Invalid request body ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/document-settings" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "title": "string", "termsAndConditions": "string", "footerText": "string", "manufactureTitle": "string", "manufactureText": "string", "showAdditionalProductInfo": true }' ``` --- # Get Document Footer Logo `GET https://api.guidelab.co/document-settings/logo` Serve the document footer logo image from R2 storage for the current lab. Documentation: https://docs.guidelab.co/api-reference/document-settings/getDocumentFooterLogo ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Footer logo image binary ### 404: Document settings or footer logo not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/document-settings/logo" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload Document Footer Logo `POST https://api.guidelab.co/document-settings/logo` Upload a new footer logo for documents. Replaces any existing footer logo. Accepts JPEG, PNG, WebP, or GIF up to 5MB. Documentation: https://docs.guidelab.co/api-reference/document-settings/uploadDocumentFooterLogo ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Successfully uploaded footer logo with updated settings - `settings` (object) **(required)**: - `id` (string,null) **(required)**: - `labId` (string) **(required)**: - `documentType` (string) **(required)**: - `title` (string,null) **(required)**: - `termsAndConditions` (string,null) **(required)**: - `footerText` (string,null) **(required)**: - `footerLogoKey` (string,null) **(required)**: - `manufactureTitle` (string,null) **(required)**: - `manufactureText` (string,null) **(required)**: - `showAdditionalProductInfo` (boolean) **(required)**: - `createdAt` (string,null) **(required)**: - `updatedAt` (string,null) **(required)**: ### 400: Invalid file type or file too large ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/document-settings/logo" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Document Footer Logo `DELETE https://api.guidelab.co/document-settings/logo` Remove the document footer logo from R2 storage and clear the reference in the document settings. Documentation: https://docs.guidelab.co/api-reference/document-settings/deleteDocumentFooterLogo ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Footer logo successfully removed - `settings` (object) **(required)**: - `id` (string,null) **(required)**: - `labId` (string) **(required)**: - `documentType` (string) **(required)**: - `title` (string,null) **(required)**: - `termsAndConditions` (string,null) **(required)**: - `footerText` (string,null) **(required)**: - `footerLogoKey` (string,null) **(required)**: - `manufactureTitle` (string,null) **(required)**: - `manufactureText` (string,null) **(required)**: - `showAdditionalProductInfo` (boolean) **(required)**: - `createdAt` (string,null) **(required)**: - `updatedAt` (string,null) **(required)**: - `message` (string) **(required)**: ### 400: No logo to delete ### 404: Document settings not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/document-settings/logo" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Regulatory documents checklist for the lab's country `GET https://api.guidelab.co/compliance` Documentation: https://docs.guidelab.co/api-reference/compliance/getComplianceOverview ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Checklist, compliance profile and device classification - `jurisdiction` (object) **(required)**: - `code` (string) **(required)**: - `regime` (string) **(required)**: - `languages` (string[]) **(required)**: - `documentLanguage` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `profile` (object) **(required)**: - `version` (number) **(required)**: Values: `1` - `legalRepresentative` (object) **(required)**: - `name` (string,null) **(required)**: - `role` (string,null) **(required)**: - `prrc` (object) **(required)**: - `name` (string,null) **(required)**: - `qualification` (string,null) **(required)**: - `deputyName` (string,null) **(required)**: - `registrationNumber` (string,null) **(required)**: - `technicalManager` (object) **(required)**: - `name` (string,null) **(required)**: - `vigilanceCorrespondent` (object) **(required)**: - `name` (string,null) **(required)**: - `managementRepresentative` (object) **(required)**: - `name` (string,null) **(required)**: - `dpo` (object) **(required)**: - `name` (string,null) **(required)**: - `chemicalsContact` (object) **(required)**: - `name` (string,null) **(required)**: - `documentLanguage` (string,null) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh`, `null` - `outsourcedSites` (object[]) **(required)**: - `name` (string) **(required)**: - `address` (string,null) **(required)**: - `disinfection` (object) **(required)**: - `taskIds` (string[]) **(required)**: - `product` (string,null) **(required)**: - `hiddenTypeKeys` (string[]) **(required)**: - `categories` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `parentId` (string,null) **(required)**: - `deviceFamily` (string,null) **(required)**: Values: `fixed_prosthesis`, `implant_prosthesis`, `removable_prosthesis`, `combined_prosthesis`, `skeletal_prosthesis`, `orthodontic_appliance`, `provisional`, `occlusal_splint`, `surgical_guide`, `other_device`, `not_a_device`, `null` - `deviceClass` (string,null) **(required)**: Values: `I`, `IIa`, `IIb`, `III`, `null` - `effectiveFamily` (string,null) **(required)**: Values: `fixed_prosthesis`, `implant_prosthesis`, `removable_prosthesis`, `combined_prosthesis`, `skeletal_prosthesis`, `orthodontic_appliance`, `provisional`, `occlusal_splint`, `surgical_guide`, `other_device`, `not_a_device`, `null` - `effectiveClass` (string,null) **(required)**: Values: `I`, `IIa`, `IIb`, `III`, `null` - `activeProductCount` (integer) **(required)**: - `checklist` (object[]) **(required)**: - `key` (string) **(required)**: - `name` (string) **(required)**: - `category` (string) **(required)**: - `kind` (string) **(required)**: Values: `generated`, `register`, `per_order`, `upload` - `subject` (string) **(required)**: Values: `none`, `year`, `month`, `supplier`, `clinic`, `order` - `audiences` (string[]) **(required)**: - `requirement` (string) **(required)**: Values: `law`, `practice` - `legalBasis` (string) **(required)**: - `condition` (string,null) **(required)**: - `sources` (string[]) **(required)**: - `recurrenceMonths` (integer,null) **(required)**: - `applies` (boolean) **(required)**: - `hidden` (boolean) **(required)**: - `status` (string) **(required)**: Values: `missing`, `current`, `review_due`, `template_updated`, `expiring`, `expired` - `documentCount` (integer) **(required)**: - `latestDocument` (object,null) **(required)**: - `id` (string) **(required)**: - `typeKey` (string) **(required)**: - `subjectKey` (string) **(required)**: - `shared` (boolean) **(required)**: - `latestRevision` (object,null) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: ### 422: The lab's country has no compliance catalog - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/compliance" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Save the lab data shared by compliance documents `PUT https://api.guidelab.co/compliance/profile` Documentation: https://docs.guidelab.co/api-reference/compliance/updateComplianceProfile ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `profile` (object) **(required)**: - `version` (number) **(required)**: Values: `1` - `legalRepresentative` (object) **(required)**: - `name` (string,null) **(required)**: - `role` (string,null) **(required)**: - `prrc` (object) **(required)**: - `name` (string,null) **(required)**: - `qualification` (string,null) **(required)**: - `deputyName` (string,null) **(required)**: - `registrationNumber` (string,null) **(required)**: - `technicalManager` (object) **(required)**: - `name` (string,null) **(required)**: - `vigilanceCorrespondent` (object) **(required)**: - `name` (string,null) **(required)**: - `managementRepresentative` (object) **(required)**: - `name` (string,null) **(required)**: - `dpo` (object) **(required)**: - `name` (string,null) **(required)**: - `chemicalsContact` (object) **(required)**: - `name` (string,null) **(required)**: - `documentLanguage` (string,null) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh`, `null` - `outsourcedSites` (object[]) **(required)**: - `name` (string) **(required)**: - `address` (string,null) **(required)**: - `disinfection` (object) **(required)**: - `taskIds` (string[]) **(required)**: - `product` (string,null) **(required)**: ## Responses ### 200: Profile saved - `ok` (boolean) **(required)**: Values: `true` ## Example ```bash curl -X PUT "https://api.guidelab.co/compliance/profile" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "profile": { "version": 1, "legalRepresentative": { "name": "string", "role": "string" }, "prrc": { "name": "string", "qualification": "string", "deputyName": "string" }, "registrationNumber": "string", "technicalManager": { "name": "string" }, "vigilanceCorrespondent": { "name": "string" }, "managementRepresentative": { "name": "string" }, "dpo": { "name": "string" }, "chemicalsContact": { "name": "string" }, "documentLanguage": "en", "outsourcedSites": [ { "name": "string", "address": "string" } ], "disinfection": { "taskIds": [ "string" ], "product": "string" } } }' ``` --- # Mark a document type not applicable to the lab, or applicable again `PUT https://api.guidelab.co/compliance/types/{typeKey}/hidden` Documentation: https://docs.guidelab.co/api-reference/compliance/setComplianceTypeHidden ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `typeKey` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `hidden` (boolean) **(required)**: ## Responses ### 200: Saved - `hidden` (boolean) **(required)**: ### 404: Unknown document type - `error` (string) **(required)**: ## Example ```bash curl -X PUT "https://api.guidelab.co/compliance/types/{typeKey}/hidden" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "hidden": true }' ``` --- # Set the device family and class of product categories `PUT https://api.guidelab.co/compliance/classification` Documentation: https://docs.guidelab.co/api-reference/compliance/updateComplianceClassification ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `categories` (object[]) **(required)**: - `id` (string) **(required)**: - `deviceFamily` (string,null) **(required)**: Values: `fixed_prosthesis`, `implant_prosthesis`, `removable_prosthesis`, `combined_prosthesis`, `skeletal_prosthesis`, `orthodontic_appliance`, `provisional`, `occlusal_splint`, `surgical_guide`, `other_device`, `not_a_device`, `null` - `deviceClass` (string,null) **(required)**: Values: `I`, `IIa`, `IIb`, `III`, `null` ## Responses ### 200: Classification saved - `ok` (boolean) **(required)**: Values: `true` ### 404: A category is not one of the lab's - `error` (string) **(required)**: ## Example ```bash curl -X PUT "https://api.guidelab.co/compliance/classification" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "categories": [ { "id": "string", "deviceFamily": "fixed_prosthesis", "deviceClass": "I" } ] }' ``` --- # Generate a document from its template as a new revision, or start a blank one for an uploaded document type `POST https://api.guidelab.co/compliance/documents` Documentation: https://docs.guidelab.co/api-reference/compliance/generateComplianceDocument ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `typeKey` (string) **(required)**: - `subjectKey` (string): (default: ``) - `regenerate` (boolean): (default: `false`) ## Responses ### 200: The document already exists and `regenerate` was not set: returned unchanged - `document` (object) **(required)**: - `id` (string) **(required)**: - `typeKey` (string) **(required)**: - `subjectKey` (string) **(required)**: - `shared` (boolean) **(required)**: - `latestRevision` (object,null) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `revision` (object) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `content` (object,null) **(required)**: - `version` (number) **(required)**: Values: `1` - `doc` (object) **(required)**: - `revisions` (object[]) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: ### 201: The generated document and its new revision - `document` (object) **(required)**: - `id` (string) **(required)**: - `typeKey` (string) **(required)**: - `subjectKey` (string) **(required)**: - `shared` (boolean) **(required)**: - `latestRevision` (object,null) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `revision` (object) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `content` (object,null) **(required)**: - `version` (number) **(required)**: Values: `1` - `doc` (object) **(required)**: - `revisions` (object[]) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: ### 400: Neither a generated nor an uploaded document, or an invalid subject - `error` (string) **(required)**: ### 413: The lab's data makes the document larger than a document may be - `error` (string) **(required)**: ### 422: The lab's country has no compliance catalog - `error` (string) **(required)**: ### 429: Too many revisions of this document today - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/compliance/documents" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "typeKey": "string", "subjectKey": "string", "regenerate": true }' ``` --- # A document with its latest revision and revision history `GET https://api.guidelab.co/compliance/documents/{id}` Documentation: https://docs.guidelab.co/api-reference/compliance/getComplianceDocument ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Document, latest revision content and history - `document` (object) **(required)**: - `id` (string) **(required)**: - `typeKey` (string) **(required)**: - `subjectKey` (string) **(required)**: - `shared` (boolean) **(required)**: - `latestRevision` (object,null) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `revision` (object) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `content` (object,null) **(required)**: - `version` (number) **(required)**: Values: `1` - `doc` (object) **(required)**: - `revisions` (object[]) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: ### 404: Document not found - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/compliance/documents/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # One revision of a document, with its content `GET https://api.guidelab.co/compliance/documents/{id}/revisions/{number}` Documentation: https://docs.guidelab.co/api-reference/compliance/getComplianceRevision ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `number` (integer) **(required)** (in: path): ## Responses ### 200: The revision - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `content` (object,null) **(required)**: - `version` (number) **(required)**: Values: `1` - `doc` (object) **(required)**: ### 404: Revision not found - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/compliance/documents/{id}/revisions/{number}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # The uploaded file of a revision, streamed inline `GET https://api.guidelab.co/compliance/documents/{id}/revisions/{number}/file` Documentation: https://docs.guidelab.co/api-reference/compliance/getComplianceRevisionFile ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `number` (integer) **(required)** (in: path): ## Responses ### 200: The file (PDF, PNG, JPEG or WebP), private and never cached ### 404: No such revision, or it is not a file - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/compliance/documents/{id}/revisions/{number}/file" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Save the edited document as a new revision `POST https://api.guidelab.co/compliance/documents/{id}/revisions` Documentation: https://docs.guidelab.co/api-reference/compliance/saveComplianceRevision ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `baseRevisionNumber` (integer) **(required)**: - `content` (object) **(required)**: - `version` (number) **(required)**: Values: `1` - `doc` (object) **(required)**: - `note` (string,null): (default: `null`) ## Responses ### 201: The saved document - `document` (object) **(required)**: - `id` (string) **(required)**: - `typeKey` (string) **(required)**: - `subjectKey` (string) **(required)**: - `shared` (boolean) **(required)**: - `latestRevision` (object,null) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `revision` (object) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `content` (object,null) **(required)**: - `version` (number) **(required)**: Values: `1` - `doc` (object) **(required)**: - `revisions` (object[]) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: ### 404: Document not found - `error` (string) **(required)**: ### 409: Someone saved a newer revision first - `error` (string) **(required)**: - `latestRevisionNumber` (integer) **(required)**: ### 413: Document too large - `error` (string) **(required)**: ### 429: Too many revisions of this document today - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/compliance/documents/{id}/revisions" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "baseRevisionNumber": 0, "content": { "version": 1, "doc": "string" }, "note": "string" }' ``` --- # Restore an earlier revision as the newest one `POST https://api.guidelab.co/compliance/documents/{id}/restore` Documentation: https://docs.guidelab.co/api-reference/compliance/restoreComplianceRevision ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `baseRevisionNumber` (integer) **(required)**: - `revisionNumber` (integer) **(required)**: ## Responses ### 201: The document with the restored revision on top - `document` (object) **(required)**: - `id` (string) **(required)**: - `typeKey` (string) **(required)**: - `subjectKey` (string) **(required)**: - `shared` (boolean) **(required)**: - `latestRevision` (object,null) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `revision` (object) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `content` (object,null) **(required)**: - `version` (number) **(required)**: Values: `1` - `doc` (object) **(required)**: - `revisions` (object[]) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: ### 400: An uploaded file cannot be restored; upload it again - `error` (string) **(required)**: ### 404: Document or revision not found - `error` (string) **(required)**: ### 409: Someone saved a newer revision first - `error` (string) **(required)**: - `latestRevisionNumber` (integer) **(required)**: ### 429: Too many revisions of this document today - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/compliance/documents/{id}/restore" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "baseRevisionNumber": 0, "revisionNumber": 0 }' ``` --- # Share a customer-facing document with partner clinics `PUT https://api.guidelab.co/compliance/documents/{id}/share` Documentation: https://docs.guidelab.co/api-reference/compliance/shareComplianceDocument ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `shared` (boolean) **(required)**: ## Responses ### 200: Sharing updated - `shared` (boolean) **(required)**: ### 400: This document cannot be shared with clinics - `error` (string) **(required)**: ### 404: Document not found - `error` (string) **(required)**: ## Example ```bash curl -X PUT "https://api.guidelab.co/compliance/documents/{id}/share" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "shared": true }' ``` --- # Upload an issued document as the next revision `POST https://api.guidelab.co/compliance/uploads` Multipart form with `typeKey`, optional `subjectKey`, `file` (PDF, PNG, JPEG or WebP, up to 20 MB) and optional `issuedOn`, `expiresOn` (YYYY-MM-DD) and `note`. The type is read from the file's content, never from its name. Documentation: https://docs.guidelab.co/api-reference/compliance/uploadComplianceDocument ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 201: The document with the uploaded revision on top - `document` (object) **(required)**: - `id` (string) **(required)**: - `typeKey` (string) **(required)**: - `subjectKey` (string) **(required)**: - `shared` (boolean) **(required)**: - `latestRevision` (object,null) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `revision` (object) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: - `content` (object,null) **(required)**: - `version` (number) **(required)**: Values: `1` - `doc` (object) **(required)**: - `revisions` (object[]) **(required)**: - `number` (integer) **(required)**: - `source` (string) **(required)**: Values: `generated`, `edited`, `uploaded`, `restored` - `language` (string) **(required)**: Values: `en`, `it`, `es`, `fr`, `de`, `nl`, `pt`, `pl`, `zh` - `templateVersion` (integer,null) **(required)**: - `note` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `createdByName` (string,null) **(required)**: - `issuedOn` (string,null) **(required)**: - `expiresOn` (string,null) **(required)**: - `file` (object,null) **(required)**: - `name` (string) **(required)**: - `contentType` (string) **(required)**: - `sizeBytes` (integer) **(required)**: ### 400: No file, an unsupported file, invalid fields, or a document type that is not uploaded - `error` (string) **(required)**: ### 413: The file is larger than 20 MB - `error` (string) **(required)**: ### 422: The lab's country has no compliance catalog - `error` (string) **(required)**: ### 429: Upload budget or daily revision ceiling reached - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/compliance/uploads" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Hold Reasons `GET https://api.guidelab.co/hold-reasons` List all hold reasons for the current lab, sorted by display order. Optionally include inactive reasons. Documentation: https://docs.guidelab.co/api-reference/hold-reasons/listHoldReasons ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` () (in: query): Default: `false` ## Responses ### 200: List of hold reasons for the lab - `reasons` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `requiresFileReupload` (boolean) **(required)**: - `autoFillNotes` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `truncated` (boolean) **(required)**: True when the lab holds more reasons than one response returns. The list is capped, not refused. ### 400: Invalid query parameters ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/hold-reasons" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Hold Reason `POST https://api.guidelab.co/hold-reasons` Create a new hold reason for the lab. Automatically assigns the next sort order if not specified. Documentation: https://docs.guidelab.co/api-reference/hold-reasons/createHoldReason ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `sortOrder` (integer): - `requiresFileReupload` (boolean): - `autoFillNotes` (string,null): ## Responses ### 201: Newly created hold reason - `reason` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `requiresFileReupload` (boolean) **(required)**: - `autoFillNotes` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 404: Lab not found ### 409: Hold reason row limit reached ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/hold-reasons" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "sortOrder": 0, "requiresFileReupload": true, "autoFillNotes": "string" }' ``` --- # Reorder Hold Reasons `POST https://api.guidelab.co/hold-reasons/reorder` Reorder hold reasons by providing an ordered array of reason IDs. Each reason's sort order is updated to match its position. Documentation: https://docs.guidelab.co/api-reference/hold-reasons/reorderHoldReasons ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `reasonIds` (string[]) **(required)**: ## Responses ### 200: Hold reasons successfully reordered - `success` (boolean) **(required)**: ### 400: Invalid request body ### 404: One or more hold reasons not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/hold-reasons/reorder" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "reasonIds": [ "string" ] }' ``` --- # Delete Hold Reason `DELETE https://api.guidelab.co/hold-reasons/{id}` Soft-delete a hold reason by marking it as inactive. The reason remains in the database for historical reference. Documentation: https://docs.guidelab.co/api-reference/hold-reasons/deleteHoldReason ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Hold reason ID ## Responses ### 200: Hold reason deactivated - `reason` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `requiresFileReupload` (boolean) **(required)**: - `autoFillNotes` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 404: Hold reason not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/hold-reasons/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Hold Reason `PUT https://api.guidelab.co/hold-reasons/{id}` Update an existing hold reason's name, active status, file reupload requirement, or auto-fill notes. Documentation: https://docs.guidelab.co/api-reference/hold-reasons/updateHoldReason ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Hold reason ID ## Request Body Content-Type: `application/json` - `name` (string): - `isActive` (boolean): - `requiresFileReupload` (boolean): - `autoFillNotes` (string,null): ## Responses ### 200: Successfully updated hold reason - `reason` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `requiresFileReupload` (boolean) **(required)**: - `autoFillNotes` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 404: Hold reason not found ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/hold-reasons/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "isActive": true, "requiresFileReupload": true, "autoFillNotes": "string" }' ``` --- # List Qc Checklist Items `GET https://api.guidelab.co/qc-checklist` List all quality control checklist items for the current lab, sorted by display order. Optionally include inactive items. Documentation: https://docs.guidelab.co/api-reference/qc-checklist/listQcChecklistItems ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` (boolean,null) (in: query): Default: `false` ## Responses ### 200: List of QC checklist items for the lab - `items` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid query parameters ### 409: QC checklist row limit exceeded ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/qc-checklist" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Qc Checklist Item `POST https://api.guidelab.co/qc-checklist` Create a new quality control checklist item for the lab. Automatically assigns the next sort order if not specified. Documentation: https://docs.guidelab.co/api-reference/qc-checklist/createQcChecklistItem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `sortOrder` (integer): (default: `0`) - `isActive` (boolean): (default: `true`) ## Responses ### 201: Newly created QC checklist item - `item` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 409: QC checklist item limit reached ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/qc-checklist" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "sortOrder": 0, "isActive": true }' ``` --- # Reorder Qc Checklist Items `POST https://api.guidelab.co/qc-checklist/reorder` Reorder QC checklist items by providing an ordered array of item IDs. Each item's sort order is updated to match its position. Documentation: https://docs.guidelab.co/api-reference/qc-checklist/reorderQcChecklistItems ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `ids` (string[]) **(required)**: ## Responses ### 200: QC checklist items successfully reordered - `success` (boolean) **(required)**: ### 400: Invalid request body ### 404: One or more QC checklist items not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/qc-checklist/reorder" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "ids": [ "string" ] }' ``` --- # Delete Qc Checklist Item `DELETE https://api.guidelab.co/qc-checklist/{id}` Soft-delete a QC checklist item by marking it as inactive. The item remains in the database for historical reference. Documentation: https://docs.guidelab.co/api-reference/qc-checklist/deleteQcChecklistItem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): QC checklist item ID ## Responses ### 200: QC checklist item deactivated - `item` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 404: QC checklist item not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/qc-checklist/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Qc Checklist Item `PUT https://api.guidelab.co/qc-checklist/{id}` Update an existing QC checklist item's name, active status, or sort order. Documentation: https://docs.guidelab.co/api-reference/qc-checklist/updateQcChecklistItem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): QC checklist item ID ## Request Body Content-Type: `application/json` - `name` (string): - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 200: Successfully updated QC checklist item - `item` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 404: QC checklist item not found ### 409: Active QC checklist item limit reached ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/qc-checklist/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "sortOrder": 0, "isActive": true }' ``` --- # Get Qc Settings `GET https://api.guidelab.co/qc-settings` Retrieve quality control settings for the current lab. Returns an unpersisted default projection with QC disabled when no row exists; writes occur only through the manager-guarded update command. Documentation: https://docs.guidelab.co/api-reference/qc-settings/getQcSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: QC settings for the current lab - `settings` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `qcEnabled` (boolean) **(required)**: - `selectAllEnabled` (boolean) **(required)**: - `automationEnabled` (boolean) **(required)**: - `automationId` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/qc-settings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Qc Settings `PUT https://api.guidelab.co/qc-settings` Update quality control settings for the current lab. Creates default settings if none exist (upsert). Controls QC enabled state, select-all, and automation. Documentation: https://docs.guidelab.co/api-reference/qc-settings/updateQcSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `qcEnabled` (boolean): - `selectAllEnabled` (boolean): - `automationEnabled` (boolean): - `automationId` (string,null): ## Responses ### 200: Successfully updated QC settings - `settings` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `qcEnabled` (boolean) **(required)**: - `selectAllEnabled` (boolean) **(required)**: - `automationEnabled` (boolean) **(required)**: - `automationId` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/qc-settings" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "qcEnabled": true, "selectAllEnabled": true, "automationEnabled": true, "automationId": "string" }' ``` --- # List Receiving Categories `GET https://api.guidelab.co/receiving-categories` List all persisted receiving categories for the current lab with optional sources. Defaults are initialized during organization creation or by the explicit settings-defaults command. Documentation: https://docs.guidelab.co/api-reference/receiving/listReceivingCategories ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` () (in: query): Default: `false` - `includeSources` () (in: query): Default: `true` ## Responses ### 200: List of receiving categories with optional nested sources - `categories` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string,null) **(required)**: - `description` (string,null) **(required)**: - `showInFlow` (boolean) **(required)**: - `settings` (object,null) **(required)**: - `unitsPerItemLimit` (integer): - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `sources` (object[]): - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid query parameters ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/receiving-categories" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Remake Reasons `GET https://api.guidelab.co/remake-reasons` List all remake reasons for the current lab, sorted by display order. Each reason includes its associated discount percentage. Documentation: https://docs.guidelab.co/api-reference/remake-reasons/listRemakeReasons ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` () (in: query): Default: `false` ## Responses ### 200: List of remake reasons for the lab - `reasons` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `discountPercent` (number) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `truncated` (boolean) **(required)**: True when the lab holds more reasons than one response returns. The list is capped, not refused. ### 400: Invalid query parameters ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/remake-reasons" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Remake Reason `POST https://api.guidelab.co/remake-reasons` Create a new remake reason with an optional discount percentage. Automatically assigns the next sort order if not specified. Documentation: https://docs.guidelab.co/api-reference/remake-reasons/createRemakeReason ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `discountPercent` (integer,null): (default: `0`) - `sortOrder` (integer): (default: `0`) - `isActive` (boolean): (default: `true`) ## Responses ### 201: Newly created remake reason - `reason` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `discountPercent` (number) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 404: Lab not found ### 409: Remake reason row limit reached ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/remake-reasons" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "discountPercent": "string", "sortOrder": 0, "isActive": true }' ``` --- # Reorder Remake Reasons `POST https://api.guidelab.co/remake-reasons/reorder` Reorder remake reasons by providing an ordered array of reason IDs. Each reason's sort order is updated to match its position. Documentation: https://docs.guidelab.co/api-reference/remake-reasons/reorderRemakeReasons ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `ids` (string[]) **(required)**: ## Responses ### 200: Remake reasons successfully reordered - `success` (boolean) **(required)**: ### 400: Invalid request body ### 404: One or more remake reasons not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/remake-reasons/reorder" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "ids": [ "string" ] }' ``` --- # Delete Remake Reason `DELETE https://api.guidelab.co/remake-reasons/{id}` Soft-delete a remake reason by marking it as inactive. The reason remains in the database for historical reference. Documentation: https://docs.guidelab.co/api-reference/remake-reasons/deleteRemakeReason ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Remake reason ID ## Responses ### 200: Remake reason deactivated - `reason` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `discountPercent` (number) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 404: Remake reason not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/remake-reasons/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Remake Reason `PUT https://api.guidelab.co/remake-reasons/{id}` Update an existing remake reason's name, discount percentage, active status, or sort order. Documentation: https://docs.guidelab.co/api-reference/remake-reasons/updateRemakeReason ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Remake reason ID ## Request Body Content-Type: `application/json` - `name` (string): - `discountPercent` (integer,null): - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 200: Successfully updated remake reason - `reason` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `discountPercent` (number) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 404: Remake reason not found ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/remake-reasons/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "discountPercent": "string", "sortOrder": 0, "isActive": true }' ``` --- # The lab's production equipment with next due dates `GET https://api.guidelab.co/equipment` Documentation: https://docs.guidelab.co/api-reference/equipment/listEquipment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeRetired` (string) (in: query): Values: `true`, `false` ## Responses ### 200: Equipment - `equipment` (object[]) **(required)**: - `name` (string) **(required)**: - `category` (string) **(required)**: Values: `milling`, `furnace`, `printer_3d`, `scanner`, `casting`, `sandblaster`, `suction`, `compressor`, `polymerisation`, `other` - `manufacturer` (string,null): (default: `null`) - `model` (string,null): (default: `null`) - `serialNumber` (string,null): (default: `null`) - `roomId` (string,null): (default: `null`) - `commissionedOn` (string,null): (default: `null`) - `status` (string): (default: `active`) Values: `active`, `retired` - `maintenanceIntervalMonths` (integer,null): (default: `null`) - `calibrationIntervalMonths` (integer,null): (default: `null`) - `safetyCheckIntervalMonths` (integer,null): (default: `null`) - `notes` (string,null): (default: `null`) - `id` (string) **(required)**: - `maintenanceDueOn` (string,null) **(required)**: - `calibrationDueOn` (string,null) **(required)**: - `safetyCheckDueOn` (string,null) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/equipment" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Add a machine `POST https://api.guidelab.co/equipment` Documentation: https://docs.guidelab.co/api-reference/equipment/createEquipment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `category` (string) **(required)**: Values: `milling`, `furnace`, `printer_3d`, `scanner`, `casting`, `sandblaster`, `suction`, `compressor`, `polymerisation`, `other` - `manufacturer` (string,null): (default: `null`) - `model` (string,null): (default: `null`) - `serialNumber` (string,null): (default: `null`) - `roomId` (string,null): (default: `null`) - `commissionedOn` (string,null): (default: `null`) - `status` (string): (default: `active`) Values: `active`, `retired` - `maintenanceIntervalMonths` (integer,null): (default: `null`) - `calibrationIntervalMonths` (integer,null): (default: `null`) - `safetyCheckIntervalMonths` (integer,null): (default: `null`) - `notes` (string,null): (default: `null`) ## Responses ### 201: The machine - `name` (string) **(required)**: - `category` (string) **(required)**: Values: `milling`, `furnace`, `printer_3d`, `scanner`, `casting`, `sandblaster`, `suction`, `compressor`, `polymerisation`, `other` - `manufacturer` (string,null): (default: `null`) - `model` (string,null): (default: `null`) - `serialNumber` (string,null): (default: `null`) - `roomId` (string,null): (default: `null`) - `commissionedOn` (string,null): (default: `null`) - `status` (string): (default: `active`) Values: `active`, `retired` - `maintenanceIntervalMonths` (integer,null): (default: `null`) - `calibrationIntervalMonths` (integer,null): (default: `null`) - `safetyCheckIntervalMonths` (integer,null): (default: `null`) - `notes` (string,null): (default: `null`) - `id` (string) **(required)**: - `maintenanceDueOn` (string,null) **(required)**: - `calibrationDueOn` (string,null) **(required)**: - `safetyCheckDueOn` (string,null) **(required)**: ### 400: Unknown production room - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/equipment" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "category": "milling" }' ``` --- # Update or retire a machine `PUT https://api.guidelab.co/equipment/{id}` Documentation: https://docs.guidelab.co/api-reference/equipment/updateEquipment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `category` (string) **(required)**: Values: `milling`, `furnace`, `printer_3d`, `scanner`, `casting`, `sandblaster`, `suction`, `compressor`, `polymerisation`, `other` - `manufacturer` (string,null): (default: `null`) - `model` (string,null): (default: `null`) - `serialNumber` (string,null): (default: `null`) - `roomId` (string,null): (default: `null`) - `commissionedOn` (string,null): (default: `null`) - `status` (string): (default: `active`) Values: `active`, `retired` - `maintenanceIntervalMonths` (integer,null): (default: `null`) - `calibrationIntervalMonths` (integer,null): (default: `null`) - `safetyCheckIntervalMonths` (integer,null): (default: `null`) - `notes` (string,null): (default: `null`) ## Responses ### 200: The machine - `name` (string) **(required)**: - `category` (string) **(required)**: Values: `milling`, `furnace`, `printer_3d`, `scanner`, `casting`, `sandblaster`, `suction`, `compressor`, `polymerisation`, `other` - `manufacturer` (string,null): (default: `null`) - `model` (string,null): (default: `null`) - `serialNumber` (string,null): (default: `null`) - `roomId` (string,null): (default: `null`) - `commissionedOn` (string,null): (default: `null`) - `status` (string): (default: `active`) Values: `active`, `retired` - `maintenanceIntervalMonths` (integer,null): (default: `null`) - `calibrationIntervalMonths` (integer,null): (default: `null`) - `safetyCheckIntervalMonths` (integer,null): (default: `null`) - `notes` (string,null): (default: `null`) - `id` (string) **(required)**: - `maintenanceDueOn` (string,null) **(required)**: - `calibrationDueOn` (string,null) **(required)**: - `safetyCheckDueOn` (string,null) **(required)**: ### 400: Unknown production room - `error` (string) **(required)**: ### 404: Machine not found - `error` (string) **(required)**: ## Example ```bash curl -X PUT "https://api.guidelab.co/equipment/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "category": "milling" }' ``` --- # Maintenance, calibration and safety-check log of a machine `GET https://api.guidelab.co/equipment/{id}/logs` Documentation: https://docs.guidelab.co/api-reference/equipment/listEquipmentLogs ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Most recent entries first - `logs` (object[]) **(required)**: - `kind` (string) **(required)**: Values: `maintenance`, `calibration`, `safety_check` - `performedOn` (string) **(required)**: - `description` (string,null): (default: `null`) - `performedByName` (string) **(required)**: - `id` (string) **(required)**: - `equipmentId` (string) **(required)**: - `createdAt` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/equipment/{id}/logs" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Record a maintenance, calibration or safety check `POST https://api.guidelab.co/equipment/{id}/logs` Documentation: https://docs.guidelab.co/api-reference/equipment/createEquipmentLog ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `kind` (string) **(required)**: Values: `maintenance`, `calibration`, `safety_check` - `performedOn` (string) **(required)**: - `description` (string,null): (default: `null`) - `performedByName` (string) **(required)**: ## Responses ### 201: The machine with its updated due dates - `name` (string) **(required)**: - `category` (string) **(required)**: Values: `milling`, `furnace`, `printer_3d`, `scanner`, `casting`, `sandblaster`, `suction`, `compressor`, `polymerisation`, `other` - `manufacturer` (string,null): (default: `null`) - `model` (string,null): (default: `null`) - `serialNumber` (string,null): (default: `null`) - `roomId` (string,null): (default: `null`) - `commissionedOn` (string,null): (default: `null`) - `status` (string): (default: `active`) Values: `active`, `retired` - `maintenanceIntervalMonths` (integer,null): (default: `null`) - `calibrationIntervalMonths` (integer,null): (default: `null`) - `safetyCheckIntervalMonths` (integer,null): (default: `null`) - `notes` (string,null): (default: `null`) - `id` (string) **(required)**: - `maintenanceDueOn` (string,null) **(required)**: - `calibrationDueOn` (string,null) **(required)**: - `safetyCheckDueOn` (string,null) **(required)**: ### 404: Machine not found - `error` (string) **(required)**: ### 409: The machine is retired - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/equipment/{id}/logs" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "kind": "maintenance", "performedOn": "string", "description": "string", "performedByName": "string" }' ``` --- # List Sticker Template Categories `GET https://api.guidelab.co/sticker-templates/categories` List sticker template categories for the lab with pagination, search, and template count per category. Clinic users must provide a labId. Documentation: https://docs.guidelab.co/api-reference/sticker-templates/listStickerTemplateCategories ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` (string) (in: query): Default: `false` - `search` (string) (in: query): - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `50` - `labId` (string) (in: query): ## Responses ### 200: Paginated list of sticker template categories with template counts - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `templateCount` (number) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters or missing labId for clinic users ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/sticker-templates/categories" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Sticker Template Category `POST https://api.guidelab.co/sticker-templates/categories` Create a new sticker template category for organizing sticker templates. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/sticker-templates/createStickerTemplateCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `description` (string): - `sortOrder` (integer): (default: `0`) - `isActive` (boolean): (default: `true`) ## Responses ### 201: Newly created sticker template category - `category` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `templateCount` (number) **(required)**: ### 400: Invalid request body ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/sticker-templates/categories" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string", "sortOrder": 0, "isActive": true }' ``` --- # Get Sticker Template Category `GET https://api.guidelab.co/sticker-templates/categories/{id}` Retrieve a single sticker template category by ID. Documentation: https://docs.guidelab.co/api-reference/sticker-templates/getStickerTemplateCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Sticker template category details - `category` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 404: Category not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/sticker-templates/categories/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Sticker Template Category `DELETE https://api.guidelab.co/sticker-templates/categories/{id}` Soft-delete a sticker template category by marking it as inactive. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/sticker-templates/deleteStickerTemplateCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Category deactivated - `success` (boolean) **(required)**: ### 404: Category not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/sticker-templates/categories/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Sticker Template Category `PUT https://api.guidelab.co/sticker-templates/categories/{id}` Update a sticker template category's name, description, sort order, or active status. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/sticker-templates/updateStickerTemplateCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `name` (string): - `description` (string): - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 200: Successfully updated sticker template category - `category` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 404: Category not found ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/sticker-templates/categories/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string", "sortOrder": 0, "isActive": true }' ``` --- # Generate Sticker Pdf `POST https://api.guidelab.co/sticker-templates/generate` Generate sticker PDF data for a specific order using a template. Resolves order variables (patient, clinic, doctor, product category) and returns processed template data with inputs for PDF generation. Documentation: https://docs.guidelab.co/api-reference/sticker-templates/generateStickerPdf ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `templateId` (string) **(required)**: - `orderId` (string) **(required)**: - `copies` (integer): (default: `1`) ## Responses ### 200: Processed sticker template with resolved variables and PDF inputs - `template` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `width` (string) **(required)**: - `height` (string) **(required)**: - `templateData` (object) **(required)**: - `basePdf` (object) **(required)**: - `schemas` (array[]) **(required)**: - `sampledata` (object[]): - `previewImageKey` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `variables` (object) **(required)**: - `inputs` (object[]) **(required)**: - `copies` (number) **(required)**: ### 400: Invalid request body ### 404: Template or order not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/sticker-templates/generate" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "templateId": "string", "orderId": "string", "copies": 0 }' ``` --- # List Sticker Templates `GET https://api.guidelab.co/sticker-templates` List sticker templates for the lab with pagination, search, and optional category filtering. Includes joined category data. Clinic users must provide a labId. Documentation: https://docs.guidelab.co/api-reference/sticker-templates/listStickerTemplates ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `categoryId` (string) (in: query): - `includeInactive` (string) (in: query): Default: `false` - `search` (string) (in: query): - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `50` - `labId` (string) (in: query): ## Responses ### 200: Paginated list of sticker templates with category details - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `width` (string) **(required)**: - `height` (string) **(required)**: - `templateData` (object) **(required)**: - `basePdf` (object) **(required)**: - `schemas` (array[]) **(required)**: - `sampledata` (object[]): - `previewImageKey` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `category` (object,null) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters or missing labId for clinic users ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/sticker-templates" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Sticker Template `POST https://api.guidelab.co/sticker-templates` Create a new sticker template with dimensions, template data, and optional category. If marked as default, unsets the previous default template. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/sticker-templates/createStickerTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `categoryId` (string,null): - `name` (string) **(required)**: - `description` (string): - `width` (number): (default: `50`) - `height` (number): (default: `25`) - `templateData` (object) **(required)**: - `basePdf` (object) **(required)**: - `schemas` (array[]) **(required)**: - `sampledata` (object[]): - `isDefault` (boolean): (default: `false`) - `sortOrder` (integer): (default: `0`) - `isActive` (boolean): (default: `true`) ## Responses ### 201: Newly created sticker template - `template` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `width` (string) **(required)**: - `height` (string) **(required)**: - `templateData` (object) **(required)**: - `basePdf` (object) **(required)**: - `schemas` (array[]) **(required)**: - `sampledata` (object[]): - `previewImageKey` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body or category not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/sticker-templates" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "templateData": { "basePdf": "string", "schemas": [ [ {} ] ], "sampledata": [ {} ] } }' ``` --- # Get Sticker Template `GET https://api.guidelab.co/sticker-templates/{id}` Retrieve a single sticker template by ID, including its full template data and joined category information. Documentation: https://docs.guidelab.co/api-reference/sticker-templates/getStickerTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Sticker template details with category - `template` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `width` (string) **(required)**: - `height` (string) **(required)**: - `templateData` (object) **(required)**: - `basePdf` (object) **(required)**: - `schemas` (array[]) **(required)**: - `sampledata` (object[]): - `previewImageKey` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `category` (object,null) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 404: Template not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/sticker-templates/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Sticker Template `DELETE https://api.guidelab.co/sticker-templates/{id}` Soft-delete a sticker template by marking it as inactive. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/sticker-templates/deleteStickerTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Sticker template deactivated - `success` (boolean) **(required)**: ### 404: Template not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/sticker-templates/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Sticker Template `PUT https://api.guidelab.co/sticker-templates/{id}` Update an existing sticker template's properties including name, dimensions, template data, category, and default status. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/sticker-templates/updateStickerTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `categoryId` (string,null): - `name` (string): - `description` (string): - `width` (number): - `height` (number): - `templateData` (object): - `basePdf` (object) **(required)**: - `schemas` (array[]) **(required)**: - `sampledata` (object[]): - `isDefault` (boolean): - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 200: Successfully updated sticker template - `template` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `width` (string) **(required)**: - `height` (string) **(required)**: - `templateData` (object) **(required)**: - `basePdf` (object) **(required)**: - `schemas` (array[]) **(required)**: - `sampledata` (object[]): - `previewImageKey` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body or category not found ### 404: Template not found ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/sticker-templates/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Preview Sticker Template `GET https://api.guidelab.co/sticker-templates/{id}/preview` Generate a preview of a sticker template with sample variables substituted. Returns processed template data ready for rendering. Documentation: https://docs.guidelab.co/api-reference/sticker-templates/previewStickerTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Sticker template preview with sample variables applied - `template` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `width` (string) **(required)**: - `height` (string) **(required)**: - `templateData` (object) **(required)**: - `basePdf` (object) **(required)**: - `schemas` (array[]) **(required)**: - `sampledata` (object[]): - `previewImageKey` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `sampleVariables` (object) **(required)**: ### 404: Template not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/sticker-templates/{id}/preview" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Sticker Template Preview Image `GET https://api.guidelab.co/sticker-templates/{id}/preview-image` Serve the managed preview image for a sticker template. Documentation: https://docs.guidelab.co/api-reference/sticker-templates/getStickerTemplatePreviewImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Sticker preview image binary ### 404: Template or preview image not found ## Example ```bash curl -X GET "https://api.guidelab.co/sticker-templates/{id}/preview-image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload Sticker Template Preview Image `POST https://api.guidelab.co/sticker-templates/{id}/preview-image` Upload or replace a sticker template preview image. Documentation: https://docs.guidelab.co/api-reference/sticker-templates/uploadStickerTemplatePreviewImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Preview image attached - `previewImageKey` (string) **(required)**: ### 400: Invalid image ### 404: Template not found ## Example ```bash curl -X POST "https://api.guidelab.co/sticker-templates/{id}/preview-image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Sticker Template Preview Image `DELETE https://api.guidelab.co/sticker-templates/{id}/preview-image` Detach a sticker preview image and queue its object deletion. Documentation: https://docs.guidelab.co/api-reference/sticker-templates/deleteStickerTemplatePreviewImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Preview image removed - `success` (boolean) **(required)**: ### 404: Template or preview image not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/sticker-templates/{id}/preview-image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get pickup request settings `GET https://api.guidelab.co/pickup-requests/settings` Retrieve pickup request form settings for the current lab, including whether the form is enabled and thank-you message configuration. Lab only. Documentation: https://docs.guidelab.co/api-reference/pickup-requests/getPickupRequestSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Pickup request settings with form-enabled status and thank-you messages - `settings` (object) **(required)**: - `id` (string,null) **(required)**: - `labId` (string) **(required)**: - `formEnabled` (boolean) **(required)**: - `thankYouTitle` (string) **(required)**: - `thankYouMessage` (string) **(required)**: - `createdAt` (string,null) **(required)**: - `updatedAt` (string,null) **(required)**: ### 401: Unauthorized ### 403: Forbidden - lab only ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/pickup-requests/settings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update pickup request settings `PUT https://api.guidelab.co/pickup-requests/settings` Update pickup request form settings. Creates default settings if none exist. Supports partial updates. Lab only. Documentation: https://docs.guidelab.co/api-reference/pickup-requests/updatePickupRequestSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `formEnabled` (boolean): - `thankYouTitle` (string): - `thankYouMessage` (string): ## Responses ### 200: Updated pickup request settings - `settings` (object): ### 400: Invalid request body ### 401: Unauthorized ### 403: Forbidden - lab only ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/pickup-requests/settings" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "formEnabled": true, "thankYouTitle": "string", "thankYouMessage": "string" }' ``` --- # List pickup form elements `GET https://api.guidelab.co/pickup-requests/elements` Retrieve paginated form elements for the pickup request form. Elements are ordered by sortOrder. Optionally includes inactive elements. Lab only. Documentation: https://docs.guidelab.co/api-reference/pickup-requests/listPickupFormElements ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` () (in: query): Default: `false` - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `50` ## Responses ### 200: Ordered list of form elements - `elements` (array) **(required)**: ### 400: Invalid query parameters ### 401: Unauthorized ### 403: Forbidden - lab only ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/pickup-requests/elements" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a pickup form element `POST https://api.guidelab.co/pickup-requests/elements` Add a new form element to the pickup request form. If no sortOrder is specified, it will be appended at the end. Lab only. Documentation: https://docs.guidelab.co/api-reference/pickup-requests/createPickupFormElement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `elementType` (string) **(required)**: Values: `header`, `subheader`, `text`, `textarea`, `address`, `email`, `phone`, `date`, `checkbox` - `label` (string) **(required)**: - `placeholder` (string): - `helpText` (string): - `isRequired` (boolean): (default: `false`) - `sortOrder` (integer): (default: `0`) - `isActive` (boolean): (default: `true`) ## Responses ### 201: Form element created - `element` (object): ### 400: Invalid request body ### 401: Unauthorized ### 403: Forbidden - lab only ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/pickup-requests/elements" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "elementType": "header", "label": "string" }' ``` --- # Reorder pickup form elements `PUT https://api.guidelab.co/pickup-requests/elements/reorder` Update the sort order of multiple form elements in a single request. All referenced elements must belong to the current lab. Lab only. Documentation: https://docs.guidelab.co/api-reference/pickup-requests/reorderPickupFormElements ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `items` (object[]) **(required)**: - `id` (string) **(required)**: - `sortOrder` (integer) **(required)**: ## Responses ### 200: Form elements reordered successfully - `success` (boolean) **(required)**: ### 400: Some elements not found or do not belong to this lab ### 401: Unauthorized ### 403: Forbidden - lab only ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/pickup-requests/elements/reorder" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "items": [ { "id": "string", "sortOrder": 0 } ] }' ``` --- # Get a pickup form element by ID `GET https://api.guidelab.co/pickup-requests/elements/{id}` Retrieve a single form element by its ID. Must belong to the current lab. Lab only. Documentation: https://docs.guidelab.co/api-reference/pickup-requests/getPickupFormElement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Form element details - `element` (object): ### 401: Unauthorized ### 403: Forbidden - lab only ### 404: Element not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/pickup-requests/elements/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Deactivate a pickup form element `DELETE https://api.guidelab.co/pickup-requests/elements/{id}` Soft-delete a form element by setting it to inactive. The element remains in the database but will not appear in active element lists. Lab only. Documentation: https://docs.guidelab.co/api-reference/pickup-requests/deletePickupFormElement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Form element deactivated - `element` (object): ### 401: Unauthorized ### 403: Forbidden - lab only ### 404: Element not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/pickup-requests/elements/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a pickup form element `PUT https://api.guidelab.co/pickup-requests/elements/{id}` Update one or more fields of a form element. Supports partial updates. Must belong to the current lab. Lab only. Documentation: https://docs.guidelab.co/api-reference/pickup-requests/updatePickupFormElement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `elementType` (string): Values: `header`, `subheader`, `text`, `textarea`, `address`, `email`, `phone`, `date`, `checkbox` - `label` (string): - `placeholder` (string): - `helpText` (string): - `isRequired` (boolean): - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 200: Updated form element - `element` (object): ### 400: Invalid request body ### 401: Unauthorized ### 403: Forbidden - lab only ### 404: Element not found ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/pickup-requests/elements/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Get the current pickup form for an active partnership `GET https://api.guidelab.co/pickup-requests/form/{partnershipId}` Documentation: https://docs.guidelab.co/api-reference/pickup-requests/getClinicPickupRequestForm ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `partnershipId` (string) **(required)** (in: path): ## Responses ### 200: Current immutable form revision - `formRevisionId` (string) **(required)**: - `revision` (integer) **(required)**: - `definition` (object[]) **(required)**: - `thankYouTitle` (string) **(required)**: - `thankYouMessage` (string) **(required)**: ### 401: Unauthorized ### 403: Clinic partnership access required ### 404: Pickup form not found ### 409: Pickup requests are disabled or not yet published ## Example ```bash curl -X GET "https://api.guidelab.co/pickup-requests/form/{partnershipId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List pickup requests visible to the current organization `GET https://api.guidelab.co/pickup-requests` Documentation: https://docs.guidelab.co/api-reference/pickup-requests/listPickupRequests ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `status` (string) (in: query): Values: `requested`, `scheduled`, `en_route`, `needs_reschedule`, `collected`, `cancelled` - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `50` ## Responses ### 200: Pickup requests - `requests` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `clinicId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `formRevisionId` (string) **(required)**: - `status` (string) **(required)**: - `formData` (object) **(required)**: - `requestedWindowStart` (string) **(required)**: - `requestedWindowEnd` (string) **(required)**: - `requestedTimezone` (string) **(required)**: - `scheduledWindowStart` (string,null) **(required)**: - `scheduledWindowEnd` (string,null) **(required)**: - `scheduledTimezone` (string,null) **(required)**: - `addressId` (string,null) **(required)**: - `addressSnapshot` (object) **(required)**: - `label` (string,null): - `contactName` (string,null): - `contactPhone` (string,null): - `addressLine1` (string) **(required)**: - `addressLine2` (string,null): - `city` (string) **(required)**: - `state` (string,null): - `postcode` (string) **(required)**: - `country` (string) **(required)**: - `requestedByMemberId` (string) **(required)**: - `assignedMemberId` (string,null) **(required)**: - `assignedExternalName` (string,null) **(required)**: - `assignedExternalPhone` (string,null) **(required)**: - `assignedExternalEmail` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `internalNotes` (string,null) **(required)**: - `collectedAt` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `page` (integer) **(required)**: - `limit` (integer) **(required)**: ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/pickup-requests" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a pickup request as a partner clinic `POST https://api.guidelab.co/pickup-requests` Documentation: https://docs.guidelab.co/api-reference/pickup-requests/createPickupRequest ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `partnershipId` (string) **(required)**: - `formRevisionId` (string) **(required)**: - `commandId` (string) **(required)**: - `formData` (object): (default: `[object Object]`) - `requestedWindow` (object) **(required)**: - `start` (string) **(required)**: - `end` (string) **(required)**: - `timezone` (string) **(required)**: - `address` (object) **(required)**: - `orderIds` (string[]): (default: ``) - `notes` (string,null): ## Responses ### 200: Idempotently replayed pickup request - `request` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `clinicId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `formRevisionId` (string) **(required)**: - `status` (string) **(required)**: - `formData` (object) **(required)**: - `requestedWindowStart` (string) **(required)**: - `requestedWindowEnd` (string) **(required)**: - `requestedTimezone` (string) **(required)**: - `scheduledWindowStart` (string,null) **(required)**: - `scheduledWindowEnd` (string,null) **(required)**: - `scheduledTimezone` (string,null) **(required)**: - `addressId` (string,null) **(required)**: - `addressSnapshot` (object) **(required)**: - `label` (string,null): - `contactName` (string,null): - `contactPhone` (string,null): - `addressLine1` (string) **(required)**: - `addressLine2` (string,null): - `city` (string) **(required)**: - `state` (string,null): - `postcode` (string) **(required)**: - `country` (string) **(required)**: - `requestedByMemberId` (string) **(required)**: - `assignedMemberId` (string,null) **(required)**: - `assignedExternalName` (string,null) **(required)**: - `assignedExternalPhone` (string,null) **(required)**: - `assignedExternalEmail` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `internalNotes` (string,null) **(required)**: - `collectedAt` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 201: Pickup request created - `request` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `clinicId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `formRevisionId` (string) **(required)**: - `status` (string) **(required)**: - `formData` (object) **(required)**: - `requestedWindowStart` (string) **(required)**: - `requestedWindowEnd` (string) **(required)**: - `requestedTimezone` (string) **(required)**: - `scheduledWindowStart` (string,null) **(required)**: - `scheduledWindowEnd` (string,null) **(required)**: - `scheduledTimezone` (string,null) **(required)**: - `addressId` (string,null) **(required)**: - `addressSnapshot` (object) **(required)**: - `label` (string,null): - `contactName` (string,null): - `contactPhone` (string,null): - `addressLine1` (string) **(required)**: - `addressLine2` (string,null): - `city` (string) **(required)**: - `state` (string,null): - `postcode` (string) **(required)**: - `country` (string) **(required)**: - `requestedByMemberId` (string) **(required)**: - `assignedMemberId` (string,null) **(required)**: - `assignedExternalName` (string,null) **(required)**: - `assignedExternalPhone` (string,null) **(required)**: - `assignedExternalEmail` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `internalNotes` (string,null) **(required)**: - `collectedAt` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid form, address, window, or orders ### 401: Unauthorized ### 403: Clinic partnership access required ### 404: Partnership, form revision, or location not found ### 409: Pickup form disabled or idempotency conflict ## Example ```bash curl -X POST "https://api.guidelab.co/pickup-requests" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "partnershipId": "string", "formRevisionId": "string", "commandId": "string", "requestedWindow": { "start": "string", "end": "string", "timezone": "string" }, "address": "string" }' ``` --- # Get a pickup request and its immutable history `GET https://api.guidelab.co/pickup-requests/{id}` Documentation: https://docs.guidelab.co/api-reference/pickup-requests/getPickupRequest ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Pickup request detail - `request` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `clinicId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `formRevisionId` (string) **(required)**: - `status` (string) **(required)**: - `formData` (object) **(required)**: - `requestedWindowStart` (string) **(required)**: - `requestedWindowEnd` (string) **(required)**: - `requestedTimezone` (string) **(required)**: - `scheduledWindowStart` (string,null) **(required)**: - `scheduledWindowEnd` (string,null) **(required)**: - `scheduledTimezone` (string,null) **(required)**: - `addressId` (string,null) **(required)**: - `addressSnapshot` (object) **(required)**: - `label` (string,null): - `contactName` (string,null): - `contactPhone` (string,null): - `addressLine1` (string) **(required)**: - `addressLine2` (string,null): - `city` (string) **(required)**: - `state` (string,null): - `postcode` (string) **(required)**: - `country` (string) **(required)**: - `requestedByMemberId` (string) **(required)**: - `assignedMemberId` (string,null) **(required)**: - `assignedExternalName` (string,null) **(required)**: - `assignedExternalPhone` (string,null) **(required)**: - `assignedExternalEmail` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `internalNotes` (string,null) **(required)**: - `collectedAt` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `orderIds` (string[]) **(required)**: - `attempts` (object[]) **(required)**: - `id` (string) **(required)**: - `attemptNumber` (integer) **(required)**: - `outcome` (string) **(required)**: - `notes` (string,null) **(required)**: - `attemptedAt` (string) **(required)**: - `events` (object[]) **(required)**: - `id` (string) **(required)**: - `sequence` (integer) **(required)**: - `eventType` (string) **(required)**: - `fromStatus` (string,null) **(required)**: - `toStatus` (string,null) **(required)**: - `payload` (object) **(required)**: - `createdAt` (string) **(required)**: ### 401: Unauthorized ### 404: Pickup request not found ## Example ```bash curl -X GET "https://api.guidelab.co/pickup-requests/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Edit a clinic pickup request before it is scheduled `PUT https://api.guidelab.co/pickup-requests/{id}` Documentation: https://docs.guidelab.co/api-reference/pickup-requests/updateRequestedPickup ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `commandId` (string) **(required)**: - `formData` (object): - `requestedWindow` (object): - `start` (string) **(required)**: - `end` (string) **(required)**: - `timezone` (string) **(required)**: - `address` (object): - `orderIds` (string[]): - `notes` (string,null): ## Responses ### 200: Updated or idempotently replayed pickup request - `request` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `clinicId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `formRevisionId` (string) **(required)**: - `status` (string) **(required)**: - `formData` (object) **(required)**: - `requestedWindowStart` (string) **(required)**: - `requestedWindowEnd` (string) **(required)**: - `requestedTimezone` (string) **(required)**: - `scheduledWindowStart` (string,null) **(required)**: - `scheduledWindowEnd` (string,null) **(required)**: - `scheduledTimezone` (string,null) **(required)**: - `addressId` (string,null) **(required)**: - `addressSnapshot` (object) **(required)**: - `label` (string,null): - `contactName` (string,null): - `contactPhone` (string,null): - `addressLine1` (string) **(required)**: - `addressLine2` (string,null): - `city` (string) **(required)**: - `state` (string,null): - `postcode` (string) **(required)**: - `country` (string) **(required)**: - `requestedByMemberId` (string) **(required)**: - `assignedMemberId` (string,null) **(required)**: - `assignedExternalName` (string,null) **(required)**: - `assignedExternalPhone` (string,null) **(required)**: - `assignedExternalEmail` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `internalNotes` (string,null) **(required)**: - `collectedAt` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid form, address, window, or orders ### 401: Unauthorized ### 403: Clinic access required ### 404: Pickup request not found ### 409: Request is scheduled or command conflicts ## Example ```bash curl -X PUT "https://api.guidelab.co/pickup-requests/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "commandId": "string", "formData": {}, "requestedWindow": { "start": "string", "end": "string", "timezone": "string" }, "address": "string", "orderIds": [ "string" ], "notes": "string" }' ``` --- # Schedule, assign, route, collect, reschedule, or cancel a pickup `POST https://api.guidelab.co/pickup-requests/{id}/commands` Documentation: https://docs.guidelab.co/api-reference/pickup-requests/commandPickupRequest ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` ## Responses ### 200: Command applied or idempotently replayed - `request` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `clinicId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `formRevisionId` (string) **(required)**: - `status` (string) **(required)**: - `formData` (object) **(required)**: - `requestedWindowStart` (string) **(required)**: - `requestedWindowEnd` (string) **(required)**: - `requestedTimezone` (string) **(required)**: - `scheduledWindowStart` (string,null) **(required)**: - `scheduledWindowEnd` (string,null) **(required)**: - `scheduledTimezone` (string,null) **(required)**: - `addressId` (string,null) **(required)**: - `addressSnapshot` (object) **(required)**: - `label` (string,null): - `contactName` (string,null): - `contactPhone` (string,null): - `addressLine1` (string) **(required)**: - `addressLine2` (string,null): - `city` (string) **(required)**: - `state` (string,null): - `postcode` (string) **(required)**: - `country` (string) **(required)**: - `requestedByMemberId` (string) **(required)**: - `assignedMemberId` (string,null) **(required)**: - `assignedExternalName` (string,null) **(required)**: - `assignedExternalPhone` (string,null) **(required)**: - `assignedExternalEmail` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `internalNotes` (string,null) **(required)**: - `collectedAt` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid command ### 401: Unauthorized ### 403: Lab access required ### 404: Pickup request or assignee not found ### 409: Stale status or idempotency conflict ## Example ```bash curl -X POST "https://api.guidelab.co/pickup-requests/{id}/commands" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '"string"' ``` --- # Record a pickup attempt `POST https://api.guidelab.co/pickup-requests/{id}/attempts` Documentation: https://docs.guidelab.co/api-reference/pickup-requests/createPickupAttempt ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `commandId` (string) **(required)**: - `outcome` (string) **(required)**: Values: `collected`, `no_answer`, `not_ready`, `address_issue`, `other` - `notes` (string,null): - `attemptedAt` (string): ## Responses ### 200: Attempt recorded or idempotently replayed - `request` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `clinicId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `formRevisionId` (string) **(required)**: - `status` (string) **(required)**: - `formData` (object) **(required)**: - `requestedWindowStart` (string) **(required)**: - `requestedWindowEnd` (string) **(required)**: - `requestedTimezone` (string) **(required)**: - `scheduledWindowStart` (string,null) **(required)**: - `scheduledWindowEnd` (string,null) **(required)**: - `scheduledTimezone` (string,null) **(required)**: - `addressId` (string,null) **(required)**: - `addressSnapshot` (object) **(required)**: - `label` (string,null): - `contactName` (string,null): - `contactPhone` (string,null): - `addressLine1` (string) **(required)**: - `addressLine2` (string,null): - `city` (string) **(required)**: - `state` (string,null): - `postcode` (string) **(required)**: - `country` (string) **(required)**: - `requestedByMemberId` (string) **(required)**: - `assignedMemberId` (string,null) **(required)**: - `assignedExternalName` (string,null) **(required)**: - `assignedExternalPhone` (string,null) **(required)**: - `assignedExternalEmail` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `internalNotes` (string,null) **(required)**: - `collectedAt` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `attempt` (object) **(required)**: - `id` (string) **(required)**: - `attemptNumber` (integer) **(required)**: - `outcome` (string) **(required)**: - `notes` (string,null) **(required)**: - `attemptedAt` (string) **(required)**: ### 401: Unauthorized ### 403: Lab access required ### 404: Pickup request not found ### 409: Pickup is not en route or command conflicts ## Example ```bash curl -X POST "https://api.guidelab.co/pickup-requests/{id}/attempts" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "commandId": "string", "outcome": "collected", "notes": "string", "attemptedAt": "string" }' ``` --- # List Email Templates `GET https://api.guidelab.co/email-templates` List email templates for the current lab with filtering by category, search, and pagination. Supports including inactive templates. Documentation: https://docs.guidelab.co/api-reference/email-templates/listEmailTemplates ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `category` (string) (in: query): Values: `general`, `order`, `invoice`, `shipment`, `notification`, `marketing` - `includeInactive` () (in: query): - `search` (string) (in: query): - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `50` ## Responses ### 200: Paginated list of email templates - `templates` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `subject` (string) **(required)**: - `description` (string,null) **(required)**: - `designJson` (object) **(required)**: - `body` (object) **(required)**: - `rows` (array) **(required)**: - `counters` (object): - `htmlContent` (string) **(required)**: - `category` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: ### 400: Invalid query parameters ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/email-templates" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Email Template `POST https://api.guidelab.co/email-templates` Create a new email template with design JSON and HTML content. Supports categorization (general, order, invoice, shipment, notification, marketing). Documentation: https://docs.guidelab.co/api-reference/email-templates/createEmailTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `subject` (string) **(required)**: - `description` (string): - `designJson` (object) **(required)**: - `body` (object) **(required)**: - `rows` (array) **(required)**: - `counters` (object): - `htmlContent` (string) **(required)**: - `category` (string): (default: `general`) Values: `general`, `order`, `invoice`, `shipment`, `notification`, `marketing` - `sortOrder` (integer): (default: `0`) - `isActive` (boolean): (default: `true`) ## Responses ### 201: Newly created email template - `template` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `subject` (string) **(required)**: - `description` (string,null) **(required)**: - `designJson` (object) **(required)**: - `body` (object) **(required)**: - `rows` (array) **(required)**: - `counters` (object): - `htmlContent` (string) **(required)**: - `category` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/email-templates" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "subject": "string", "designJson": { "body": { "rows": [ "string" ] }, "counters": {} }, "htmlContent": "string" }' ``` --- # Get Email Template `GET https://api.guidelab.co/email-templates/{id}` Retrieve a single email template by ID, including its full design JSON and HTML content. Documentation: https://docs.guidelab.co/api-reference/email-templates/getEmailTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Email template details - `template` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `subject` (string) **(required)**: - `description` (string,null) **(required)**: - `designJson` (object) **(required)**: - `body` (object) **(required)**: - `rows` (array) **(required)**: - `counters` (object): - `htmlContent` (string) **(required)**: - `category` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 404: Email template not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/email-templates/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Email Template `DELETE https://api.guidelab.co/email-templates/{id}` Soft-delete an email template by marking it as inactive. The template remains in the database for historical reference. Documentation: https://docs.guidelab.co/api-reference/email-templates/deleteEmailTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Email template deactivated - `success` (boolean) **(required)**: ### 404: Email template not found ### 409: Template is used by an active production task ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/email-templates/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Email Template `PUT https://api.guidelab.co/email-templates/{id}` Update an existing email template's name, subject, content, category, or other properties. Documentation: https://docs.guidelab.co/api-reference/email-templates/updateEmailTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `name` (string): - `subject` (string): - `description` (string): - `designJson` (object): - `body` (object) **(required)**: - `rows` (array) **(required)**: - `counters` (object): - `htmlContent` (string): - `category` (string): Values: `general`, `order`, `invoice`, `shipment`, `notification`, `marketing` - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 200: Successfully updated email template - `template` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `subject` (string) **(required)**: - `description` (string,null) **(required)**: - `designJson` (object) **(required)**: - `body` (object) **(required)**: - `rows` (array) **(required)**: - `counters` (object): - `htmlContent` (string) **(required)**: - `category` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 404: Email template not found ### 409: Template is used by an active production task ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/email-templates/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Get Scanner Settings `GET https://api.guidelab.co/scanner-settings` Retrieve scanner settings for the current organization, including auto-pool case amount, disconnection email preferences, and folder paths. Documentation: https://docs.guidelab.co/api-reference/scanner-settings/getScannerSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Scanner settings for the current organization - `settings` (object) **(required)**: - `id` (string,null) **(required)**: - `organizationId` (string) **(required)**: - `autoPoolCaseAmount` (number) **(required)**: - `sendDisconnectionEmail` (boolean) **(required)**: - `disconnectionEmailRecipients` (string[]) **(required)**: - `newOrderFolderPath` (string,null) **(required)**: - `existingOrderFolderPath` (string,null) **(required)**: - `useScanhubLite` (boolean) **(required)**: - `createdAt` (string,null) **(required)**: - `updatedAt` (string,null) **(required)**: ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/scanner-settings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Scanner Settings `PUT https://api.guidelab.co/scanner-settings` Update scanner settings for the current organization. Creates default settings if none exist (upsert). Controls auto-pool amount, disconnection emails, folder paths, and ScanHub Lite mode. Documentation: https://docs.guidelab.co/api-reference/scanner-settings/updateScannerSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `autoPoolCaseAmount` (integer,null): - `sendDisconnectionEmail` (boolean): - `disconnectionEmailRecipients` (string[]): - `newOrderFolderPath` (string,null): - `existingOrderFolderPath` (string,null): - `useScanhubLite` (boolean): ## Responses ### 200: Successfully updated scanner settings - `settings` (object) **(required)**: - `id` (string,null) **(required)**: - `organizationId` (string) **(required)**: - `autoPoolCaseAmount` (number) **(required)**: - `sendDisconnectionEmail` (boolean) **(required)**: - `disconnectionEmailRecipients` (string[]) **(required)**: - `newOrderFolderPath` (string,null) **(required)**: - `existingOrderFolderPath` (string,null) **(required)**: - `useScanhubLite` (boolean) **(required)**: - `createdAt` (string,null) **(required)**: - `updatedAt` (string,null) **(required)**: ### 400: Invalid request body ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/scanner-settings" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "autoPoolCaseAmount": "string", "sendDisconnectionEmail": true, "disconnectionEmailRecipients": [ "string" ], "newOrderFolderPath": "string", "existingOrderFolderPath": "string", "useScanhubLite": true }' ``` --- # List a clinic patient's scanner sessions `GET https://api.guidelab.co/scanner-connections/scans` Documentation: https://docs.guidelab.co/api-reference/scanner-connections/listPatientScannerSessions ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `patientId` (string) **(required)** (in: query): - `orderId` (string) (in: query): - `treatmentPhaseId` (string) (in: query): - `cursor` (string) (in: query): - `history` (string) (in: query): Values: `true` ## Responses ### 200: Normalized scanner sessions with coverage and connection health - `sessions` (object[]) **(required)**: - `id` (string) **(required)**: - `sourceId` (string): - `revision` (string) **(required)**: - `connectionId` (string) **(required)**: - `connectionName` (string) **(required)**: - `scannerType` (string) **(required)**: Values: `3shape`, `itero`, `medit`, `alliedstar`, `shining3d` - `providerReference` (object) **(required)**: - `kind` (string) **(required)**: Values: `case`, `order` - `caseId` (string): - `orderId` (string): - `rxId` (string): - `regionId` (integer): - `caseNumber` (string) **(required)**: - `patientName` (string,null) **(required)**: - `scannedAt` (string,null) **(required)**: [date-time] - `completed` (boolean) **(required)**: - `matchedPatientId` (string,null) **(required)**: - `confidence` (number) **(required)**: - `autoAttachAllowed` (boolean) **(required)**: - `history` (boolean): - `files` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `mimeType` (string): - `size` (integer): - `kind` (string): Values: `upper`, `lower`, `bite`, `supporting` - `nextCursor` (string,null) **(required)**: - `complete` (boolean) **(required)**: - `autoAttachSessionId` (string,null) **(required)**: - `health` (object[]) **(required)**: - `connectionId` (string) **(required)**: - `status` (string) **(required)**: Values: `ready`, `catching_up`, `partial`, `blocked`, `error` ### 400: Invalid cursor ### 401: Unauthorized ### 403: Clinic access required ### 404: Patient or draft unavailable ### 429: Scanner history budget exceeded ## Example ```bash curl -X GET "https://api.guidelab.co/scanner-connections/scans" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Attach or dismiss the latest confidently matched scanner session `POST https://api.guidelab.co/scanner-connections/scans/auto-attach` Documentation: https://docs.guidelab.co/api-reference/scanner-connections/selectAutomaticScannerSession ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` ## Responses ### 200: Selection state - `jobId` (string): - `status` (string) **(required)**: Values: `pending`, `complete`, `dismissed`, `stale`, `failed` - `files` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `size` (integer) **(required)**: - `mimeType` (string) **(required)**: - `thumbnailUrl` (string,null) **(required)**: - `fileRequirementId` (string,null): - `fileRequirementSlotId` (string,null): - `treatmentPhaseId` (string,null): - `scannerSourceKey` (string): ### 202: Import queued - `jobId` (string): - `status` (string) **(required)**: Values: `pending`, `complete`, `dismissed`, `stale`, `failed` - `files` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `size` (integer) **(required)**: - `mimeType` (string) **(required)**: - `thumbnailUrl` (string,null) **(required)**: - `fileRequirementId` (string,null): - `fileRequirementSlotId` (string,null): - `treatmentPhaseId` (string,null): - `scannerSourceKey` (string): ### 400: Invalid phase ### 401: Unauthorized ### 403: Clinic access required ### 404: Draft or session unavailable ### 409: Draft or partnership is not writable ### 503: Import is unavailable ## Example ```bash curl -X POST "https://api.guidelab.co/scanner-connections/scans/auto-attach" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '"string"' ``` --- # Get a scanner import's progress and files `GET https://api.guidelab.co/scanner-connections/import-jobs/{jobId}` Documentation: https://docs.guidelab.co/api-reference/scanner-connections/getScannerImportJob ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `jobId` (string) **(required)** (in: path): ## Responses ### 200: Import job - `jobId` (string) **(required)**: - `status` (string) **(required)**: Values: `pending`, `running`, `complete`, `failed`, `stale`, `dismissed` - `files` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `size` (integer) **(required)**: - `mimeType` (string) **(required)**: - `thumbnailUrl` (string,null) **(required)**: - `fileRequirementId` (string,null): - `fileRequirementSlotId` (string,null): - `treatmentPhaseId` (string,null): - `scannerSourceKey` (string): - `error` (string): ### 401: Unauthorized ### 404: Import job unavailable ## Example ```bash curl -X GET "https://api.guidelab.co/scanner-connections/import-jobs/{jobId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Retry a failed scanner import after user action `POST https://api.guidelab.co/scanner-connections/import-jobs/{jobId}/retry` Documentation: https://docs.guidelab.co/api-reference/scanner-connections/retryScannerImportJob ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `jobId` (string) **(required)** (in: path): ## Responses ### 202: Import retry state - `jobId` (string) **(required)**: - `status` (string) **(required)**: Values: `pending`, `running`, `complete`, `failed`, `stale`, `dismissed` - `files` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `size` (integer) **(required)**: - `mimeType` (string) **(required)**: - `thumbnailUrl` (string,null) **(required)**: - `fileRequirementId` (string,null): - `fileRequirementSlotId` (string,null): - `treatmentPhaseId` (string,null): - `scannerSourceKey` (string): - `error` (string): ### 401: Unauthorized ### 404: Import job unavailable ### 409: The draft is payment locked ## Example ```bash curl -X POST "https://api.guidelab.co/scanner-connections/import-jobs/{jobId}/retry" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Allied Star Order Prefill `GET https://api.guidelab.co/scanner-connections/alliedstar/prefill` Resolve an Alliedstar case code into New Order wizard prefill data. Returns 404 when the case was never delivered to the caller's organization, so a case belonging to another clinic is indistinguishable from one that does not exist. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/getAlliedStarOrderPrefill ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `caseCode` (string) **(required)** (in: query): ## Responses ### 200: Prefill data for the New Order wizard ### 400: Missing or invalid case code ### 404: No such case for this organization ## Example ```bash curl -X GET "https://api.guidelab.co/scanner-connections/alliedstar/prefill" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Handle Allied Star Authorization Callback `GET https://api.guidelab.co/scanner-connections/alliedstar/callback` Handle the Alliedstar authorization return using a session-bound state query parameter. Only the privately configured sandbox account can enroll; unsigned identities do not establish customer account ownership. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/handleAlliedStarAuthorizationCallback ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `state` (string) (in: query): - `openid` (string) (in: query): - `unionid` (string) (in: query): - `region` (string) (in: query): ## Responses ### 302: Redirect to scanner settings page ## Example ```bash curl -X GET "https://api.guidelab.co/scanner-connections/alliedstar/callback" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Handle Allied Star Authorization Callback With State `GET https://api.guidelab.co/scanner-connections/alliedstar/callback/:state` Compatibility callback for session-bound state in the path. Only the privately configured sandbox account can enroll. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/handleAlliedStarAuthorizationCallbackWithState ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `state` (string) **(required)** (in: path): - `state` (string) (in: query): - `openid` (string) (in: query): - `unionid` (string) (in: query): - `region` (string) (in: query): ## Responses ### 302: Redirect to scanner settings page ## Example ```bash curl -X GET "https://api.guidelab.co/scanner-connections/alliedstar/callback/:state" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Scanner Connections `GET https://api.guidelab.co/scanner-connections` List all scanner connections for the current organization. Optionally filter by scanner type and include inactive connections. Includes Medit group metadata when available. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/listScannerConnections ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` () (in: query): - `scannerType` (string) (in: query): Values: `3shape`, `itero`, `medit`, `alliedstar`, `shining3d` ## Responses ### 200: List of scanner connections with metadata - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `scannerType` (string) **(required)**: - `name` (string) **(required)**: - `connectionStatus` (string) **(required)**: - `statusMessage` (string,null) **(required)**: - `testMode` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `lastConnectedAt` (string,null) **(required)**: - `lastSyncAt` (string,null) **(required)**: - `meditGroupName` (string,null) **(required)**: - `meditGroupType` (string,null) **(required)**: ### 400: Invalid query parameters ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/scanner-connections" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Scanner Connection `POST https://api.guidelab.co/scanner-connections` Create a new scanner connection for the organization. Supports the implemented Medit, 3Shape, and iTero providers. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/createScannerConnection ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `scannerType` (string) **(required)**: Values: `3shape`, `itero`, `medit`, `alliedstar`, `shining3d` - `name` (string) **(required)**: - `testMode` (boolean): (default: `false`) - `sortOrder` (integer): (default: `0`) ## Responses ### 201: Newly created scanner connection - `connection` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `scannerType` (string) **(required)**: - `name` (string) **(required)**: - `connectionStatus` (string) **(required)**: - `statusMessage` (string,null) **(required)**: - `testMode` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `lastConnectedAt` (string,null) **(required)**: - `lastSyncAt` (string,null) **(required)**: ### 400: Invalid request body ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/scanner-connections" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "scannerType": "3shape", "name": "string", "testMode": true, "sortOrder": 0 }' ``` --- # Handle Medit O Auth Callback `GET https://api.guidelab.co/scanner-connections/medit/callback` Handle the Medit OAuth callback after user authorization. Exchanges the authorization code for tokens, stores encrypted credentials, and redirects to scanner settings. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/handleMeditOAuthCallback ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 302: Redirect to scanner settings page after OAuth flow ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/scanner-connections/medit/callback" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Handle Itero O Auth Callback `GET https://api.guidelab.co/scanner-connections/itero/callback` Handle the iTero OAuth callback after user authorization. Exchanges the authorization code for tokens, discovers the API region, and pairs the account if exactly one available account is found. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/handleIteroOAuthCallback ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 302: Redirect to scanner settings page after OAuth flow ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/scanner-connections/itero/callback" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Handle3 Shape O Auth Callback `GET https://api.guidelab.co/scanner-connections/3shape/callback` Handle the 3Shape OAuth callback after user authorization. Exchanges the code using PKCE, stores encrypted tokens, and discovers active regions. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/handle3ShapeOAuthCallback ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 302: Redirect to scanner settings page after OAuth flow ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/scanner-connections/3shape/callback" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Handle Shining3d O Auth Callback `GET https://api.guidelab.co/scanner-connections/shining3d/callback` Handle the Shining 3D Dental Cloud consent return. Owner-only: redeems the code to learn the user's institutions, binds the one that granted GuideLab orders access in Dental Cloud, stores no provider token, and redirects to scanner settings. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/handleShining3dOAuthCallback ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 302: Redirect to scanner settings page after consent ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/scanner-connections/shining3d/callback" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Scanner Connection `GET https://api.guidelab.co/scanner-connections/{id}` Retrieve a single scanner connection by ID, including scanner-type-specific metadata (e.g. Medit group info). Documentation: https://docs.guidelab.co/api-reference/scanner-connections/getScannerConnection ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Scanner connection details with metadata - `connection` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `scannerType` (string) **(required)**: - `name` (string) **(required)**: - `connectionStatus` (string) **(required)**: - `statusMessage` (string,null) **(required)**: - `testMode` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `lastConnectedAt` (string,null) **(required)**: - `lastSyncAt` (string,null) **(required)**: - `meditGroupName` (string,null) **(required)**: - `meditGroupType` (string,null) **(required)**: ### 404: Connection not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/scanner-connections/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Scanner Connection `DELETE https://api.guidelab.co/scanner-connections/{id}` Delete a scanner connection. Releases provider access where the provider supports it (iTero unpair and token revocation, Medit webhook deletion, 3Shape token revocation), removes stored credentials and provider account details, and marks the connection inactive. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/deleteScannerConnection ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Scanner connection deactivated - `success` (boolean) **(required)**: ### 404: Connection not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/scanner-connections/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Scanner Connection `PUT https://api.guidelab.co/scanner-connections/{id}` Update a scanner connection's name, test mode, sort order, or active status. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/updateScannerConnection ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `name` (string): - `testMode` (boolean): - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 200: Successfully updated scanner connection - `connection` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `scannerType` (string) **(required)**: - `name` (string) **(required)**: - `connectionStatus` (string) **(required)**: - `statusMessage` (string,null) **(required)**: - `testMode` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `lastConnectedAt` (string,null) **(required)**: - `lastSyncAt` (string,null) **(required)**: ### 400: Invalid request body ### 404: Connection not found ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/scanner-connections/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "testMode": true, "sortOrder": 0, "isActive": true }' ``` --- # Disconnect Scanner Connection `POST https://api.guidelab.co/scanner-connections/{id}/disconnect` Disconnect a scanner connection. Releases provider access first where the provider supports it (iTero unpair and token revocation, Medit webhook deletion, 3Shape token revocation), then removes stored tokens and provider account details and resets the status to disconnected. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/disconnectScannerConnection ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Scanner connection successfully disconnected - `success` (boolean) **(required)**: - `connection` (object): - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `scannerType` (string) **(required)**: - `name` (string) **(required)**: - `connectionStatus` (string) **(required)**: - `statusMessage` (string,null) **(required)**: - `testMode` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `lastConnectedAt` (string,null) **(required)**: - `lastSyncAt` (string,null) **(required)**: ### 404: Connection not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/scanner-connections/{id}/disconnect" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Test Scanner Connection `POST https://api.guidelab.co/scanner-connections/{id}/test` Test a scanner connection by attempting an API call to the scanner provider. Supports Medit, 3Shape, and iTero. Updates connection status based on the test result. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/testScannerConnection ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Test result with success status and scanner details - `success` (boolean) **(required)**: - `message` (string): - `details` (object): ### 404: Connection not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/scanner-connections/{id}/test" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Sync Scanner Connection `POST https://api.guidelab.co/scanner-connections/{id}/sync` Run one bounded synchronization slice through the shared scanner inbox pipeline. Returns ingested counts and whether historical catch-up is complete. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/syncScannerConnection ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Sync result with fetched data - `success` (boolean) **(required)**: - `data` (object): - `syncedAt` (string) **(required)**: - `complete` (boolean): - `newItems` (number): - `updatedItems` (number): - `totalFetched` (number): - `error` (string): - `async` (boolean): - `jobId` (string): ### 400: Scanner not connected or sync not supported ### 404: Connection not found ### 429: Scanner sync budget exceeded ### 500: Sync failed ## Example ```bash curl -X POST "https://api.guidelab.co/scanner-connections/{id}/sync" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Scanner Connection Cases `GET https://api.guidelab.co/scanner-connections/{id}/cases` Operationally list cases/orders from a scanner connection with pagination, search, and date range filtering. Provider access may idempotently refresh an expired token and record connection health; this endpoint is not a tenant-settings inspection read. Supports Medit, 3Shape, iTero and Alliedstar scanners. Medit clinic search matches case titles; unsupported provider searches filter only the current page. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/listScannerConnectionCases ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `page` (integer) (in: query): Default: `1` - `pageSize` (integer) (in: query): Default: `20` - `search` (string) (in: query): - `from` () (in: query): - `to` () (in: query): - `regionId` (integer) (in: query): ## Responses ### 200: Paginated list of scanner cases/orders ### 400: Scanner not connected or invalid query parameters ### 401: Unauthorized or token expired ### 404: Connection not found ### 500: Internal server error ### 502: Regional discovery failed ## Example ```bash curl -X GET "https://api.guidelab.co/scanner-connections/{id}/cases" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Scanner Connection Case `GET https://api.guidelab.co/scanner-connections/{id}/cases/{caseId}` Operationally retrieve detailed information about a specific scanner case/order. Provider access may idempotently refresh an expired token and record connection health; this endpoint is not a tenant-settings inspection read. Supports Medit, 3Shape (searches active regions), iTero and Alliedstar scanners. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/getScannerConnectionCase ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `caseId` (string) **(required)** (in: path): - `regionId` (integer) (in: query): - `kind` (string) (in: query): Values: `case`, `order` ## Responses ### 200: Scanner case details from the provider ### 400: Scanner not connected ### 401: Unauthorized or token expired ### 404: Connection or case not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/scanner-connections/{id}/cases/{caseId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Import Scanner Case `POST https://api.guidelab.co/scanner-connections/{id}/import-case` Import a 3Shape case as a new order. Creates the order, patient (if needed), order items from model elements, and downloads attachments to R2 storage. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/importScannerCase ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `caseId` (string) **(required)**: - `regionId` (integer) **(required)**: - `labId` (string) **(required)**: - `clinicId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `patientId` (string): ## Responses ### 201: Imported case with order ID, patient, items, and file counts - `orderId` (string) **(required)**: - `orderNumber` (string) **(required)**: - `patientId` (string,null) **(required)**: - `orderItemCount` (number) **(required)**: - `fileCount` (number) **(required)**: - `threeshapeCaseId` (string) **(required)**: - `threeshapeOrderNo` (string,null) **(required)**: ### 400: Invalid request body ### 401: Unauthorized or token expired ### 404: 3Shape connection not found ### 409: Scanner case has a conflicting destination or an attachment import is already in progress ### 422: Scanner case exceeds a local import safety limit ### 429: Scanner import rate limit exceeded ### 500: Internal server error ### 503: One or more scanner attachments remain pending ## Example ```bash curl -X POST "https://api.guidelab.co/scanner-connections/{id}/import-case" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "caseId": "string", "regionId": 0, "labId": "string", "clinicId": "string", "partnershipId": "string", "patientId": "string" }' ``` --- # Import Scanner Files `POST https://api.guidelab.co/scanner-connections/{id}/import-files` Import files from a scanner case into an existing order. Uses verified provider sessions and managed private storage, including bounded ZIP and 7z extraction. Async callers receive a durable job ID. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/importScannerFiles ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` ## Responses ### 200: Import results with success and error counts - `success` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `type` (string) **(required)**: - `mimeType` (string) **(required)**: - `size` (number) **(required)**: - `url` (string) **(required)**: - `thumbnailUrl` (string,null) **(required)**: - `orderId` (string) **(required)**: - `patientId` (string,null) **(required)**: - `fileRequirementId` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `errors` (object[]) **(required)**: - `fileId` (string) **(required)**: - `fileName` (string) **(required)**: - `error` (string) **(required)**: ### 202: Durable scanner import queued - `jobId` (string) **(required)**: - `status` (string) **(required)**: ### 400: Invalid request body or scanner not connected ### 401: Unauthorized or token expired ### 404: Connection, order, or import destination not found ### 409: Provider file has a conflicting destination or its import is already in progress ### 429: Scanner import rate limit exceeded ### 500: Internal server error ### 502: Scanner provider returned inconsistent data ## Example ```bash curl -X POST "https://api.guidelab.co/scanner-connections/{id}/import-files" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '"string"' ``` --- # Initiate Scanner O Auth `POST https://api.guidelab.co/scanner-connections/{id}/oauth/authorize` Initiate authorization for a scanner connection. Returns the provider-specific URL. Supports Medit, 3Shape (with PKCE), iTero, owner-only Shining 3D Dental Cloud consent, and owner-only enrollment of the privately configured Alliedstar sandbox account. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/initiateScannerOAuth ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: OAuth authorization URL to redirect the user to - `url` (string) **(required)**: ### 400: OAuth not supported for this scanner type ### 401: Unauthorized ### 404: Connection not found ### 500: Scanner credentials not configured ## Example ```bash curl -X POST "https://api.guidelab.co/scanner-connections/{id}/oauth/authorize" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Itero Related Accounts `GET https://api.guidelab.co/scanner-connections/{id}/related-accounts` List related iTero accounts available for pairing. Only available for iTero scanner connections that have completed OAuth authentication. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/listIteroRelatedAccounts ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: List of iTero accounts available for pairing - `accounts` (object[]) **(required)**: ### 400: Not an iTero connection or not authenticated ### 404: Connection not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/scanner-connections/{id}/related-accounts" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Pair Itero Account `POST https://api.guidelab.co/scanner-connections/{id}/pair-account` Pair an iTero account with this scanner connection and store the paired tokens. Marks the connection as connected upon success. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/pairIteroAccount ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `accountId` (integer) **(required)**: ## Responses ### 200: Account successfully paired - `success` (boolean) **(required)**: - `accountId` (number) **(required)**: - `accountName` (string) **(required)**: ### 400: Not an iTero connection, not authenticated, or invalid request ### 404: Connection not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/scanner-connections/{id}/pair-account" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "accountId": 0 }' ``` --- # Setup Medit Webhook `POST https://api.guidelab.co/scanner-connections/{id}/webhook-setup` Set up or update the matching Medit webhook in place for real-time notifications about orders, cases, and files. Documentation: https://docs.guidelab.co/api-reference/scanner-connections/setupMeditWebhook ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Webhook registered successfully with endpoint details - `success` (boolean) **(required)**: - `message` (string) **(required)**: - `details` (object) **(required)**: - `endpointUuid` (string) **(required)**: - `events` (string[]) **(required)**: - `url` (string) **(required)**: ### 400: Not a Medit connection or not authorized ### 404: Connection not found ### 500: Failed to set up webhook ## Example ```bash curl -X POST "https://api.guidelab.co/scanner-connections/{id}/webhook-setup" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Whats App Templates `GET https://api.guidelab.co/whatsapp-templates` List WhatsApp message templates for the current organization with pagination, search, and status filtering. Documentation: https://docs.guidelab.co/api-reference/whatsapp-templates/listWhatsAppTemplates ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `search` (string) (in: query): - `status` (string) (in: query): Values: `draft`, `pending`, `approved`, `rejected` - `connectionId` (string) (in: query): ## Responses ### 200: Paginated list of WhatsApp templates - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `displayName` (string) **(required)**: - `description` (string,null) **(required)**: - `language` (string) **(required)**: - `category` (string) **(required)**: - `contentType` (string) **(required)**: - `body` (string) **(required)**: - `variables` (object,null) **(required)**: - `status` (string) **(required)**: - `contentSid` (string,null) **(required)**: - `rejectionReason` (string,null) **(required)**: - `lastSyncedAt` (string,null) **(required)**: - `lastSyncError` (string,null) **(required)**: - `usageCount` (number,null) **(required)**: Deprecated compatibility count; advances only for provider-accepted custom-template sends. Prefer successfulSendCount. - `successfulSendCount` (number) **(required)**: - `providerScope` (string) **(required)**: Values: `unbound`, `platform_legacy`, `lab_account`, `meta_waba` - `provider` (string,null): Values: `meta`, `twilio`, `null` - `accountState` (string) **(required)**: Values: `unbound`, `platform`, `connected`, `disconnected`, `changed` - `providerOperation` (object,null) **(required)**: - `id` (string) **(required)**: - `phase` (string) **(required)**: Values: `ready_create`, `create_ambiguous`, `ready_submit`, `ready_delete`, `manual_review` - `state` (string) **(required)**: Values: `pending`, `manual_review` - `compatibleEvents` (string[]) **(required)**: - `selectedEvents` (string[]) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/whatsapp-templates" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Whats App Template `POST https://api.guidelab.co/whatsapp-templates` Create a new WhatsApp message template in draft status. The template name is auto-prefixed with the organization slug. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/whatsapp-templates/createWhatsAppTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `nameSuffix` (string) **(required)**: - `displayName` (string) **(required)**: - `description` (string): - `language` (string): (default: `en`) - `category` (string): (default: `UTILITY`) Values: `UTILITY`, `MARKETING`, `AUTHENTICATION` - `body` (string) **(required)**: - `variables` (object): ## Responses ### 201: Newly created WhatsApp template in draft status - `template` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `displayName` (string) **(required)**: - `description` (string,null) **(required)**: - `language` (string) **(required)**: - `category` (string) **(required)**: - `contentType` (string) **(required)**: - `body` (string) **(required)**: - `variables` (object,null) **(required)**: - `status` (string) **(required)**: - `contentSid` (string,null) **(required)**: - `rejectionReason` (string,null) **(required)**: - `lastSyncedAt` (string,null) **(required)**: - `lastSyncError` (string,null) **(required)**: - `usageCount` (number,null) **(required)**: Deprecated compatibility count; advances only for provider-accepted custom-template sends. Prefer successfulSendCount. - `successfulSendCount` (number) **(required)**: - `providerScope` (string) **(required)**: Values: `unbound`, `platform_legacy`, `lab_account`, `meta_waba` - `provider` (string,null): Values: `meta`, `twilio`, `null` - `accountState` (string) **(required)**: Values: `unbound`, `platform`, `connected`, `disconnected`, `changed` - `providerOperation` (object,null) **(required)**: - `id` (string) **(required)**: - `phase` (string) **(required)**: Values: `ready_create`, `create_ambiguous`, `ready_submit`, `ready_delete`, `manual_review` - `state` (string) **(required)**: Values: `pending`, `manual_review` - `compatibleEvents` (string[]) **(required)**: - `selectedEvents` (string[]) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/whatsapp-templates" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "nameSuffix": "string", "displayName": "string", "body": "string" }' ``` --- # Sync All Whats App Templates `POST https://api.guidelab.co/whatsapp-templates/sync-all` Sync the approval status of all pending WhatsApp templates with Twilio. Updates each template's status to approved, rejected, or keeps as pending. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/whatsapp-templates/syncAllWhatsAppTemplates ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Sync results with status updates for each template - `synced` (number) **(required)**: - `hasMore` (boolean) **(required)**: - `results` (object[]) **(required)**: - `id` (string) **(required)**: - `status` (string) **(required)**: - `error` (string): ### 429: Template status sync rate limit exceeded ### 500: Twilio credentials not configured or internal error ## Example ```bash curl -X POST "https://api.guidelab.co/whatsapp-templates/sync-all" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Whats App Template Event Overrides `GET https://api.guidelab.co/whatsapp-templates/event-overrides` List the lab's automatic WhatsApp event template selections and effective platform fallbacks. Documentation: https://docs.guidelab.co/api-reference/whatsapp-templates/listWhatsAppTemplateEventOverrides ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Automatic WhatsApp event template selections - `data` (object[]) **(required)**: - `eventKey` (string) **(required)**: Values: `order_received_lab`, `order_submitted_clinic` - `selectedTemplateId` (string,null) **(required)**: - `selectedTemplate` (object,null) **(required)**: - `id` (string) **(required)**: - `displayName` (string) **(required)**: - `language` (string) **(required)**: - `effectiveSource` (string) **(required)**: Values: `override`, `platform` - `fallbackReason` (string,null) **(required)**: Values: `not_configured`, `template_ineligible`, `account_disconnected`, `account_changed`, `null` - `requiredVariables` (object) **(required)**: - `accountState` (string) **(required)**: Values: `unbound`, `platform`, `connected`, `disconnected`, `changed` ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/whatsapp-templates/event-overrides" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Whats App Template Event Candidates `GET https://api.guidelab.co/whatsapp-templates/event-overrides/{eventKey}/candidates` List a bounded page of approved, account-bound templates compatible with one automatic WhatsApp event. Documentation: https://docs.guidelab.co/api-reference/whatsapp-templates/listWhatsAppTemplateEventCandidates ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `eventKey` (string) **(required)** (in: path): Values: `order_received_lab`, `order_submitted_clinic` - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `search` (string) (in: query): ## Responses ### 200: Paginated compatible automatic WhatsApp templates - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `displayName` (string) **(required)**: - `language` (string) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/whatsapp-templates/event-overrides/{eventKey}/candidates" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Whats App Template Event Override `DELETE https://api.guidelab.co/whatsapp-templates/event-overrides/{eventKey}` Reset an automatic WhatsApp event to the GuideLab platform English template. Documentation: https://docs.guidelab.co/api-reference/whatsapp-templates/deleteWhatsAppTemplateEventOverride ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `eventKey` (string) **(required)** (in: path): Values: `order_received_lab`, `order_submitted_clinic` ## Responses ### 200: Updated automatic WhatsApp event template selections - `data` (object[]) **(required)**: - `eventKey` (string) **(required)**: Values: `order_received_lab`, `order_submitted_clinic` - `selectedTemplateId` (string,null) **(required)**: - `selectedTemplate` (object,null) **(required)**: - `id` (string) **(required)**: - `displayName` (string) **(required)**: - `language` (string) **(required)**: - `effectiveSource` (string) **(required)**: Values: `override`, `platform` - `fallbackReason` (string,null) **(required)**: Values: `not_configured`, `template_ineligible`, `account_disconnected`, `account_changed`, `null` - `requiredVariables` (object) **(required)**: - `accountState` (string) **(required)**: Values: `unbound`, `platform`, `connected`, `disconnected`, `changed` ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/whatsapp-templates/event-overrides/{eventKey}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Set Whats App Template Event Override `PUT https://api.guidelab.co/whatsapp-templates/event-overrides/{eventKey}` Select an approved, account-bound lab template for an automatic WhatsApp event. Documentation: https://docs.guidelab.co/api-reference/whatsapp-templates/setWhatsAppTemplateEventOverride ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `eventKey` (string) **(required)** (in: path): Values: `order_received_lab`, `order_submitted_clinic` ## Request Body Content-Type: `application/json` - `templateId` (string) **(required)**: ## Responses ### 200: Updated automatic WhatsApp event template selections - `data` (object[]) **(required)**: - `eventKey` (string) **(required)**: Values: `order_received_lab`, `order_submitted_clinic` - `selectedTemplateId` (string,null) **(required)**: - `selectedTemplate` (object,null) **(required)**: - `id` (string) **(required)**: - `displayName` (string) **(required)**: - `language` (string) **(required)**: - `effectiveSource` (string) **(required)**: Values: `override`, `platform` - `fallbackReason` (string,null) **(required)**: Values: `not_configured`, `template_ineligible`, `account_disconnected`, `account_changed`, `null` - `requiredVariables` (object) **(required)**: - `accountState` (string) **(required)**: Values: `unbound`, `platform`, `connected`, `disconnected`, `changed` ### 404: Template not found ### 409: Template is not eligible for this event or account ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/whatsapp-templates/event-overrides/{eventKey}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "templateId": "string" }' ``` --- # Get Whats App Template `GET https://api.guidelab.co/whatsapp-templates/{id}` Retrieve a single WhatsApp template by ID, including its body, variables, approval status, and Twilio content SID. Documentation: https://docs.guidelab.co/api-reference/whatsapp-templates/getWhatsAppTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: WhatsApp template details - `template` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `displayName` (string) **(required)**: - `description` (string,null) **(required)**: - `language` (string) **(required)**: - `category` (string) **(required)**: - `contentType` (string) **(required)**: - `body` (string) **(required)**: - `variables` (object,null) **(required)**: - `status` (string) **(required)**: - `contentSid` (string,null) **(required)**: - `rejectionReason` (string,null) **(required)**: - `lastSyncedAt` (string,null) **(required)**: - `lastSyncError` (string,null) **(required)**: - `usageCount` (number,null) **(required)**: Deprecated compatibility count; advances only for provider-accepted custom-template sends. Prefer successfulSendCount. - `successfulSendCount` (number) **(required)**: - `providerScope` (string) **(required)**: Values: `unbound`, `platform_legacy`, `lab_account`, `meta_waba` - `provider` (string,null): Values: `meta`, `twilio`, `null` - `accountState` (string) **(required)**: Values: `unbound`, `platform`, `connected`, `disconnected`, `changed` - `providerOperation` (object,null) **(required)**: - `id` (string) **(required)**: - `phase` (string) **(required)**: Values: `ready_create`, `create_ambiguous`, `ready_submit`, `ready_delete`, `manual_review` - `state` (string) **(required)**: Values: `pending`, `manual_review` - `compatibleEvents` (string[]) **(required)**: - `selectedEvents` (string[]) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 404: Template not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/whatsapp-templates/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Whats App Template `DELETE https://api.guidelab.co/whatsapp-templates/{id}` Permanently delete a WhatsApp template and its event selections, durably recovering exact-account Twilio cleanup when needed. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/whatsapp-templates/deleteWhatsAppTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Template successfully deleted - `success` (boolean) **(required)**: ### 404: Template not found ### 409: The exact legacy Twilio account is unavailable ### 429: Template deletion budget exceeded ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/whatsapp-templates/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Whats App Template `PUT https://api.guidelab.co/whatsapp-templates/{id}` Update a WhatsApp template's name, body, variables, or other properties. Only draft templates can be edited. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/whatsapp-templates/updateWhatsAppTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `nameSuffix` (string): - `displayName` (string): - `description` (string): - `language` (string): - `category` (string): Values: `UTILITY`, `MARKETING`, `AUTHENTICATION` - `body` (string): - `variables` (object): ## Responses ### 200: Successfully updated WhatsApp template - `template` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `displayName` (string) **(required)**: - `description` (string,null) **(required)**: - `language` (string) **(required)**: - `category` (string) **(required)**: - `contentType` (string) **(required)**: - `body` (string) **(required)**: - `variables` (object,null) **(required)**: - `status` (string) **(required)**: - `contentSid` (string,null) **(required)**: - `rejectionReason` (string,null) **(required)**: - `lastSyncedAt` (string,null) **(required)**: - `lastSyncError` (string,null) **(required)**: - `usageCount` (number,null) **(required)**: Deprecated compatibility count; advances only for provider-accepted custom-template sends. Prefer successfulSendCount. - `successfulSendCount` (number) **(required)**: - `providerScope` (string) **(required)**: Values: `unbound`, `platform_legacy`, `lab_account`, `meta_waba` - `provider` (string,null): Values: `meta`, `twilio`, `null` - `accountState` (string) **(required)**: Values: `unbound`, `platform`, `connected`, `disconnected`, `changed` - `providerOperation` (object,null) **(required)**: - `id` (string) **(required)**: - `phase` (string) **(required)**: Values: `ready_create`, `create_ambiguous`, `ready_submit`, `ready_delete`, `manual_review` - `state` (string) **(required)**: Values: `pending`, `manual_review` - `compatibleEvents` (string[]) **(required)**: - `selectedEvents` (string[]) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Template is not in draft status or invalid request body ### 404: Template not found ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/whatsapp-templates/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Register Whats App Template `POST https://api.guidelab.co/whatsapp-templates/{id}/register` Register a draft WhatsApp template with Twilio for WhatsApp approval. Creates the content in Twilio, submits for approval, and updates the template status to pending. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/whatsapp-templates/registerWhatsAppTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Template registered and submitted for WhatsApp approval - `template` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `displayName` (string) **(required)**: - `description` (string,null) **(required)**: - `language` (string) **(required)**: - `category` (string) **(required)**: - `contentType` (string) **(required)**: - `body` (string) **(required)**: - `variables` (object,null) **(required)**: - `status` (string) **(required)**: - `contentSid` (string,null) **(required)**: - `rejectionReason` (string,null) **(required)**: - `lastSyncedAt` (string,null) **(required)**: - `lastSyncError` (string,null) **(required)**: - `usageCount` (number,null) **(required)**: Deprecated compatibility count; advances only for provider-accepted custom-template sends. Prefer successfulSendCount. - `successfulSendCount` (number) **(required)**: - `providerScope` (string) **(required)**: Values: `unbound`, `platform_legacy`, `lab_account`, `meta_waba` - `provider` (string,null): Values: `meta`, `twilio`, `null` - `accountState` (string) **(required)**: Values: `unbound`, `platform`, `connected`, `disconnected`, `changed` - `providerOperation` (object,null) **(required)**: - `id` (string) **(required)**: - `phase` (string) **(required)**: Values: `ready_create`, `create_ambiguous`, `ready_submit`, `ready_delete`, `manual_review` - `state` (string) **(required)**: Values: `pending`, `manual_review` - `compatibleEvents` (string[]) **(required)**: - `selectedEvents` (string[]) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `providerOperation` (object) **(required)**: - `id` (string) **(required)**: - `state` (string) **(required)**: Values: `registered`, `pending` ### 202: Template registration durably accepted for bounded recovery - `template` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `displayName` (string) **(required)**: - `description` (string,null) **(required)**: - `language` (string) **(required)**: - `category` (string) **(required)**: - `contentType` (string) **(required)**: - `body` (string) **(required)**: - `variables` (object,null) **(required)**: - `status` (string) **(required)**: - `contentSid` (string,null) **(required)**: - `rejectionReason` (string,null) **(required)**: - `lastSyncedAt` (string,null) **(required)**: - `lastSyncError` (string,null) **(required)**: - `usageCount` (number,null) **(required)**: Deprecated compatibility count; advances only for provider-accepted custom-template sends. Prefer successfulSendCount. - `successfulSendCount` (number) **(required)**: - `providerScope` (string) **(required)**: Values: `unbound`, `platform_legacy`, `lab_account`, `meta_waba` - `provider` (string,null): Values: `meta`, `twilio`, `null` - `accountState` (string) **(required)**: Values: `unbound`, `platform`, `connected`, `disconnected`, `changed` - `providerOperation` (object,null) **(required)**: - `id` (string) **(required)**: - `phase` (string) **(required)**: Values: `ready_create`, `create_ambiguous`, `ready_submit`, `ready_delete`, `manual_review` - `state` (string) **(required)**: Values: `pending`, `manual_review` - `compatibleEvents` (string[]) **(required)**: - `selectedEvents` (string[]) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `providerOperation` (object) **(required)**: - `id` (string) **(required)**: - `state` (string) **(required)**: Values: `registered`, `pending` ### 400: Template is not in draft status ### 404: Template not found ### 409: Lab Twilio integration is unavailable or manual review is required ### 429: Template registration budget exceeded ### 500: Twilio credentials not configured or registration failed ## Example ```bash curl -X POST "https://api.guidelab.co/whatsapp-templates/{id}/register" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Sync Whats App Template `POST https://api.guidelab.co/whatsapp-templates/{id}/sync` Sync the approval status of a single WhatsApp template with Twilio. Requires the template to have been registered (has a contentSid). Documentation: https://docs.guidelab.co/api-reference/whatsapp-templates/syncWhatsAppTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Template with updated approval status from Twilio - `template` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `displayName` (string) **(required)**: - `description` (string,null) **(required)**: - `language` (string) **(required)**: - `category` (string) **(required)**: - `contentType` (string) **(required)**: - `body` (string) **(required)**: - `variables` (object,null) **(required)**: - `status` (string) **(required)**: - `contentSid` (string,null) **(required)**: - `rejectionReason` (string,null) **(required)**: - `lastSyncedAt` (string,null) **(required)**: - `lastSyncError` (string,null) **(required)**: - `usageCount` (number,null) **(required)**: Deprecated compatibility count; advances only for provider-accepted custom-template sends. Prefer successfulSendCount. - `successfulSendCount` (number) **(required)**: - `providerScope` (string) **(required)**: Values: `unbound`, `platform_legacy`, `lab_account`, `meta_waba` - `provider` (string,null): Values: `meta`, `twilio`, `null` - `accountState` (string) **(required)**: Values: `unbound`, `platform`, `connected`, `disconnected`, `changed` - `providerOperation` (object,null) **(required)**: - `id` (string) **(required)**: - `phase` (string) **(required)**: Values: `ready_create`, `create_ambiguous`, `ready_submit`, `ready_delete`, `manual_review` - `state` (string) **(required)**: Values: `pending`, `manual_review` - `compatibleEvents` (string[]) **(required)**: - `selectedEvents` (string[]) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Template has not been registered with Twilio ### 404: Template not found ### 409: Template's Twilio account is unavailable or changed ### 429: Template status provider-read budget exceeded ### 500: Twilio credentials not configured or internal error ## Example ```bash curl -X POST "https://api.guidelab.co/whatsapp-templates/{id}/sync" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Test Whats App Template `POST https://api.guidelab.co/whatsapp-templates/{id}/test` Send a test WhatsApp message using an approved template and the exact Twilio account that owns its Content SID. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/whatsapp-templates/testWhatsAppTemplate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `phoneNumber` (string) **(required)**: - `variables` (object): ## Responses ### 200: Test message accepted for processing - `success` (boolean) **(required)**: ### 400: Template not approved or invalid request body ### 404: Template not found ### 409: Template's Twilio account is unavailable or changed ### 429: Paid test-message rate limit exceeded ### 500: Twilio credentials not configured or send failed ### 503: Durable WhatsApp queue is unavailable ## Example ```bash curl -X POST "https://api.guidelab.co/whatsapp-templates/{id}/test" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "phoneNumber": "string", "variables": {} }' ``` --- # List scan inbox items `GET https://api.guidelab.co/scan-inbox` Retrieve paginated scan inbox items for the current scanner-owning organization. Supports filtering by status, source, and search term, with configurable sorting. Documentation: https://docs.guidelab.co/api-reference/scan-inbox/listScanInboxItems ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `pageSize` (integer) (in: query): Default: `20` - `status` (string) (in: query): - `search` (string) (in: query): - `source` (string) (in: query): - `sortBy` (string) (in: query): Values: `createdAt`, `scanDate`, `dueDate`, `patientName` Default: `createdAt` - `sortOrder` (string) (in: query): Values: `asc`, `desc` Default: `desc` ## Responses ### 200: Paginated list of scan inbox items - `items` (array) **(required)**: - `pagination` (object) **(required)**: - `total` (number) **(required)**: - `page` (number) **(required)**: - `pageSize` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/scan-inbox" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Sync scan inbox from scanner connections `POST https://api.guidelab.co/scan-inbox/sync` Queue scanner synchronization and matching. At most five eligible connections are queued per request; scheduled processing covers remaining accounts. Optionally select one connection. Documentation: https://docs.guidelab.co/api-reference/scan-inbox/syncScanInbox ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `connectionId` (string): ## Responses ### 200: Sync results with count of new items imported - `results` (object[]) **(required)**: - `connectionId` (string): - `newItems` (number) **(required)**: - `complete` (boolean): - `jobId` (string): - `totalNewItems` (number) **(required)**: - `async` (boolean): ### 400: Invalid sync request ### 401: Unauthorized ### 404: Connected scanner was not found ### 422: Sync request exceeds a local safety limit ### 429: Scanner sync budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/scan-inbox/sync" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "connectionId": "string" }' ``` --- # Bulk action on scan inbox items `POST https://api.guidelab.co/scan-inbox/bulk` Perform a bulk action (currently 'dismiss') on up to 100 scan inbox items owned by the current organization. Documentation: https://docs.guidelab.co/api-reference/scan-inbox/bulkScanInboxAction ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `action` (string) **(required)**: Values: `dismiss` - `ids` (string[]) **(required)**: - `reason` (string): ## Responses ### 200: Bulk action completed successfully - `success` (boolean) **(required)**: - `action` (string) **(required)**: - `count` (number) **(required)**: ### 400: Invalid request body ### 401: Unauthorized ## Example ```bash curl -X POST "https://api.guidelab.co/scan-inbox/bulk" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "action": "dismiss", "ids": [ "string" ], "reason": "string" }' ``` --- # Assign scan inbox item to existing order `POST https://api.guidelab.co/scan-inbox/{id}/assign` Assign a scan inbox item to an existing order. Downloads attachments from the scanner (e.g. 3Shape) and uploads them as order files. Lab only. Documentation: https://docs.guidelab.co/api-reference/scan-inbox/assignScanInboxItem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `orderId` (string) **(required)**: - `mode` (string): Values: `async` ## Responses ### 200: Item assigned to order with imported file count - `fileCount` (integer) **(required)**: - `jobId` (string): - `fileImportStatus` (string): Values: `pending`, `complete`, `failed` - `orderId` (string) **(required)**: - `orderNumber` (string) **(required)**: - `patientId` (string,null): - `orderItemCount` (integer): ### 400: Invalid request body ### 401: Unauthorized ### 403: Forbidden - lab only ### 404: Scan inbox item or order not found ### 409: Scan inbox item was handled by another request or its file import is already in progress ### 503: One or more scanner attachments remain pending ## Example ```bash curl -X POST "https://api.guidelab.co/scan-inbox/{id}/assign" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "orderId": "string", "mode": "async" }' ``` --- # Book scan inbox item as new order `POST https://api.guidelab.co/scan-inbox/{id}/book` Create a new draft order from a scan inbox item. Optionally creates a patient record and order items from scan metadata. Downloads scanner attachments as order files. Lab only. Documentation: https://docs.guidelab.co/api-reference/scan-inbox/bookScanInboxItem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `clinicId` (string): - `partnershipId` (string): - `patientId` (string): - `mode` (string): Values: `async` ## Responses ### 201: New order created from scan inbox item - `fileCount` (integer) **(required)**: - `jobId` (string): - `fileImportStatus` (string): Values: `pending`, `complete`, `failed` - `orderId` (string) **(required)**: - `orderNumber` (string) **(required)**: - `patientId` (string,null): - `orderItemCount` (integer): ### 400: Invalid booking destination ### 401: Unauthorized ### 403: Forbidden - lab only ### 404: Scan inbox item not found ### 409: Scan inbox item is already being handled ### 422: Scanner case exceeds a local import safety limit ### 429: Scanner import rate limit exceeded ### 503: One or more scanner attachments remain pending ## Example ```bash curl -X POST "https://api.guidelab.co/scan-inbox/{id}/book" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "clinicId": "string", "partnershipId": "string", "patientId": "string", "mode": "async" }' ``` --- # Dismiss a scan inbox item `POST https://api.guidelab.co/scan-inbox/{id}/dismiss` Mark an organization-owned scan inbox item as dismissed with an optional reason. The item will no longer appear in active scan inbox lists. Documentation: https://docs.guidelab.co/api-reference/scan-inbox/dismissScanInboxItem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `reason` (string): ## Responses ### 200: Scan inbox item dismissed - `success` (boolean) **(required)**: ### 401: Unauthorized ### 404: Scan inbox item not found ### 409: Scan inbox item is no longer available or its file import is already in progress ## Example ```bash curl -X POST "https://api.guidelab.co/scan-inbox/{id}/dismiss" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "reason": "string" }' ``` --- # Re-run matching for a scan inbox item `POST https://api.guidelab.co/scan-inbox/{id}/match` Trigger the matching algorithm on a scan inbox item to find tenant-visible order, patient, or clinic matches. Updates match metadata and may auto-promote status to 'matched' if confidence is high enough. Documentation: https://docs.guidelab.co/api-reference/scan-inbox/matchScanInboxItem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Match result with confidence score and matched entities - `matchedOrderId` (string,null) **(required)**: - `matchedOrderLabId` (string,null) **(required)**: - `matchedPatientId` (string,null) **(required)**: - `matchedClinicId` (string,null) **(required)**: - `confidence` (number) **(required)**: - `matchType` (string,null) **(required)**: - `reason` (string,null) **(required)**: - `status` (string) **(required)**: ### 401: Unauthorized ### 404: Scan inbox item not found ## Example ```bash curl -X POST "https://api.guidelab.co/scan-inbox/{id}/match" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get the setup guide `GET https://api.guidelab.co/setup-guide` Returns the organization's setup checklist for owners and admins: one derived completion flag per task its type shows, plus the optional tasks it skipped and when it hid the guide. Documentation: https://docs.guidelab.co/api-reference/setup-guide/getSetupGuide ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: The setup guide for the current organization - `state` (object) **(required)**: - `skipped` (string[]): (default: ``) - `hiddenAt` (string,null): (default: `null`) [date-time] - `done` (object) **(required)**: - `company` (boolean): - `connect-lab` (boolean): - `dentists` (boolean): - `scanners` (boolean): - `team` (boolean): - `categories` (boolean): - `products` (boolean): - `finances` (boolean): - `stripe` (boolean): - `workflows` (boolean): - `customers` (boolean): ### 401: Unauthorized ### 403: Owner or admin role required ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/setup-guide" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update the setup guide `PATCH https://api.guidelab.co/setup-guide` Records which optional tasks the organization skipped or when it hid the guide. Only the keys sent are replaced; completion is always derived and cannot be set. Documentation: https://docs.guidelab.co/api-reference/setup-guide/updateSetupGuide ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `skipped` (string[]): - `hiddenAt` (string,null): [date-time] ## Responses ### 200: The updated setup guide - `state` (object) **(required)**: - `skipped` (string[]): (default: ``) - `hiddenAt` (string,null): (default: `null`) [date-time] - `done` (object) **(required)**: - `company` (boolean): - `connect-lab` (boolean): - `dentists` (boolean): - `scanners` (boolean): - `team` (boolean): - `categories` (boolean): - `products` (boolean): - `finances` (boolean): - `stripe` (boolean): - `workflows` (boolean): - `customers` (boolean): ### 400: Invalid request body ### 401: Unauthorized ### 403: Owner or admin role required ### 500: Internal server error ## Example ```bash curl -X PATCH "https://api.guidelab.co/setup-guide" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "skipped": [ "dentists" ], "hiddenAt": "string" }' ``` --- # Get Microsoft 365 connection and sync status `GET https://api.guidelab.co/integrations/microsoft-365` Documentation: https://docs.guidelab.co/api-reference/integrations/getMicrosoft365Integration ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Connection status - `id` (string,null) **(required)**: - `isConfigured` (boolean) **(required)**: - `isConnected` (boolean) **(required)**: - `accountEmail` (string,null) **(required)**: - `settings` (object) **(required)**: - `calendarEnabled` (boolean) **(required)**: - `emailEnabled` (boolean) **(required)**: - `calendarId` (string,null) **(required)**: - `inboxEnabled` (boolean): - `calendarName` (string,null) **(required)**: - `isSwitchingCalendar` (boolean) **(required)**: - `lastSweepAt` (string,null) **(required)**: - `lastSuccessAt` (string,null) **(required)**: - `lastError` (string,null) **(required)**: - `pendingEvents` (integer) **(required)**: - `failedEvents` (integer) **(required)**: - `inboxConsentMissing` (boolean) **(required)**: - `inbox` (object,null) **(required)**: - `status` (string) **(required)**: - `statusMessage` (string,null) **(required)**: ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/microsoft-365" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Configure Microsoft 365 calendar and outgoing email `PUT https://api.guidelab.co/integrations/microsoft-365` Documentation: https://docs.guidelab.co/api-reference/integrations/updateMicrosoft365Integration ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `calendarEnabled` (boolean) **(required)**: - `emailEnabled` (boolean) **(required)**: - `calendarId` (string,null) **(required)**: - `inboxEnabled` (boolean): ## Responses ### 200: Updated settings - `id` (string,null) **(required)**: - `isConfigured` (boolean) **(required)**: - `isConnected` (boolean) **(required)**: - `accountEmail` (string,null) **(required)**: - `settings` (object) **(required)**: - `calendarEnabled` (boolean) **(required)**: - `emailEnabled` (boolean) **(required)**: - `calendarId` (string,null) **(required)**: - `inboxEnabled` (boolean): - `calendarName` (string,null) **(required)**: - `isSwitchingCalendar` (boolean) **(required)**: - `lastSweepAt` (string,null) **(required)**: - `lastSuccessAt` (string,null) **(required)**: - `lastError` (string,null) **(required)**: - `pendingEvents` (integer) **(required)**: - `failedEvents` (integer) **(required)**: - `inboxConsentMissing` (boolean) **(required)**: - `inbox` (object,null) **(required)**: - `status` (string) **(required)**: - `statusMessage` (string,null) **(required)**: ### 400: Request could not be completed - `error` (string) **(required)**: ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ### 409: Request could not be completed - `error` (string) **(required)**: ### 429: Request could not be completed - `error` (string) **(required)**: ### 502: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X PUT "https://api.guidelab.co/integrations/microsoft-365" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "calendarEnabled": true, "emailEnabled": true, "calendarId": "string", "inboxEnabled": true }' ``` --- # Authorize a laboratory Microsoft work account `POST https://api.guidelab.co/integrations/microsoft-365/authorize` Documentation: https://docs.guidelab.co/api-reference/integrations/authorizeMicrosoft365 ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `inbox` (boolean): ## Responses ### 200: Microsoft consent URL - `url` (string) **(required)**: [uri] ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ### 429: Request could not be completed - `error` (string) **(required)**: ### 503: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/microsoft-365/authorize" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "inbox": true }' ``` --- # Complete Microsoft 365 authorization `GET https://api.guidelab.co/integrations/microsoft-365/callback` Documentation: https://docs.guidelab.co/api-reference/integrations/handleMicrosoft365OAuthCallback ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `state` (string) (in: query): - `code` (string) (in: query): - `error` (string) (in: query): - `error_description` (string) (in: query): - `session_state` (string) (in: query): ## Responses ### 302: Return to integration settings ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/microsoft-365/callback" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List owned Outlook calendars `GET https://api.guidelab.co/integrations/microsoft-365/calendars` Documentation: https://docs.guidelab.co/api-reference/integrations/listMicrosoft365Calendars ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: At most 200 owned calendars - `calendars` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `truncated` (boolean) **(required)**: ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ### 409: Request could not be completed - `error` (string) **(required)**: ### 429: Request could not be completed - `error` (string) **(required)**: ### 502: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/microsoft-365/calendars" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Stop synchronization and remove local Microsoft credentials `POST https://api.guidelab.co/integrations/microsoft-365/disconnect` Existing Outlook events remain. Revoking Microsoft consent is available in the Microsoft account applications portal. Documentation: https://docs.guidelab.co/api-reference/integrations/disconnectMicrosoft365 ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Disconnected - `id` (string,null) **(required)**: - `isConfigured` (boolean) **(required)**: - `isConnected` (boolean) **(required)**: - `accountEmail` (string,null) **(required)**: - `settings` (object) **(required)**: - `calendarEnabled` (boolean) **(required)**: - `emailEnabled` (boolean) **(required)**: - `calendarId` (string,null) **(required)**: - `inboxEnabled` (boolean): - `calendarName` (string,null) **(required)**: - `isSwitchingCalendar` (boolean) **(required)**: - `lastSweepAt` (string,null) **(required)**: - `lastSuccessAt` (string,null) **(required)**: - `lastError` (string,null) **(required)**: - `pendingEvents` (integer) **(required)**: - `failedEvents` (integer) **(required)**: - `inboxConsentMissing` (boolean) **(required)**: - `inbox` (object,null) **(required)**: - `status` (string) **(required)**: - `statusMessage` (string,null) **(required)**: ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ### 409: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/microsoft-365/disconnect" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Resume one bounded calendar sync batch `POST https://api.guidelab.co/integrations/microsoft-365/sync` Documentation: https://docs.guidelab.co/api-reference/integrations/syncMicrosoft365Calendar ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `retryFailed` (boolean): (default: `false`) ## Responses ### 202: Sync queued or already running - `queued` (boolean) **(required)**: ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ### 409: Request could not be completed - `error` (string) **(required)**: ### 429: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/microsoft-365/sync" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "retryFailed": true }' ``` --- # Select the Xero organisation for a pending authorization `POST https://api.guidelab.co/integrations/xero/select-connection` Documentation: https://docs.guidelab.co/api-reference/integrations/selectXeroConnection ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `connectionId` (string) **(required)**: [uuid] ## Responses ### 200: Xero connection activated - `success` (boolean) **(required)**: ### 409: Selection expired or connection unavailable ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/xero/select-connection" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "connectionId": "string" }' ``` --- # Get Xero integration status `GET https://api.guidelab.co/integrations/xero` Retrieve the current Xero integration status, connection state, and configuration for the authenticated lab. Documentation: https://docs.guidelab.co/api-reference/integrations/getXeroStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Xero integration status including connection state and sync settings - `paymentImportBlocked` (boolean): - `id` (string,null) **(required)**: - `isEnabled` (boolean) **(required)**: - `isConnected` (boolean) **(required)**: - `tenantName` (string,null) **(required)**: - `config` (object): - `taxRatesInUse` (string[]): - `pendingConnections` (object[]): - `id` (string) **(required)**: - `tenantId` (string) **(required)**: - `tenantName` (string) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/xero" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Xero integration settings `PUT https://api.guidelab.co/integrations/xero` Update Xero integration settings such as default sales account, tax type, bank account, and sync preferences. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/updateXeroSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Updated Xero integration status and configuration - `id` (string,null) **(required)**: - `isEnabled` (boolean) **(required)**: - `isConnected` (boolean) **(required)**: - `tenantName` (string,null) **(required)**: - `config` (object): - `taxRatesInUse` (string[]): ### 401: Unauthorized - valid session required ## Example ```bash curl -X PUT "https://api.guidelab.co/integrations/xero" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Initiate Xero OAuth authorization `POST https://api.guidelab.co/integrations/xero/authorize` Initiate the Xero OAuth 2.0 authorization flow. Returns a URL to redirect the user to Xero's consent screen. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/initiateXeroOAuth ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Xero OAuth consent URL to redirect the user to - `url` (string) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/xero/authorize" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Handle Xero OAuth callback `GET https://api.guidelab.co/integrations/xero/callback` Handle the Xero OAuth 2.0 callback after user authorization. Exchanges the authorization code for tokens and stores them. Documentation: https://docs.guidelab.co/api-reference/integrations/handleXeroOAuthCallback ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Redirect to integration settings page with connection status ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/xero/callback" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Disconnect Xero integration `POST https://api.guidelab.co/integrations/xero/disconnect` Disconnect the Xero integration by clearing OAuth tokens while preserving configuration settings. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/disconnectXero ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Xero integration successfully disconnected - `success` (boolean) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/xero/disconnect" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Xero accounts `GET https://api.guidelab.co/integrations/xero/accounts` Fetch chart of accounts from the connected Xero organization for settings configuration. Owner/admin only; provider access may idempotently refresh and persist an expired OAuth token. Supports filtering by account type (revenue or bank). Documentation: https://docs.guidelab.co/api-reference/integrations/listXeroAccounts ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of Xero accounts with ID, code, name, type, and tax type - `data` (object[]) **(required)**: - `accountId` (string) **(required)**: - `code` (string) **(required)**: - `name` (string) **(required)**: - `type` (string) **(required)**: - `taxType` (string,null) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/xero/accounts" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Xero tax rates `GET https://api.guidelab.co/integrations/xero/tax-rates` Fetch available tax rates from the connected Xero organization for settings configuration. Owner/admin only; provider access may idempotently refresh and persist an expired OAuth token. Documentation: https://docs.guidelab.co/api-reference/integrations/listXeroTaxRates ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of Xero tax rates with name, type, and effective rate - `data` (object[]) **(required)**: - `name` (string) **(required)**: - `taxType` (string) **(required)**: - `effectiveRate` (number) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/xero/tax-rates" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Search Xero contacts `GET https://api.guidelab.co/integrations/xero/contacts/search` Search for contacts in the connected Xero organization while configuring mappings. Owner/admin only; provider access may idempotently refresh and persist an expired OAuth token. Requires a minimum 2-character query. Documentation: https://docs.guidelab.co/api-reference/integrations/searchXeroContacts ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of matching Xero contacts with ID, name, and email - `data` (object[]) **(required)**: - `contactId` (string) **(required)**: - `name` (string) **(required)**: - `email` (string,null) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/xero/contacts/search" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Xero contact mappings `GET https://api.guidelab.co/integrations/xero/contact-mappings` Retrieve all clinic-to-Xero contact mappings for the authenticated lab. Documentation: https://docs.guidelab.co/api-reference/integrations/listXeroContactMappings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of clinic-to-Xero contact mappings with match method - `data` (array) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/xero/contact-mappings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Xero contact mapping `DELETE https://api.guidelab.co/integrations/xero/contact-mappings` Remove a clinic-to-Xero contact mapping by clinic ID. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/deleteXeroContactMapping ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Contact mapping successfully deleted - `success` (boolean) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X DELETE "https://api.guidelab.co/integrations/xero/contact-mappings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upsert Xero contact mapping `PUT https://api.guidelab.co/integrations/xero/contact-mappings` Create or update a mapping between a partner clinic and a Xero contact for invoice synchronization. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/upsertXeroContactMapping ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Contact mapping successfully created or updated - `success` (boolean) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X PUT "https://api.guidelab.co/integrations/xero/contact-mappings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Sync an invoice to Xero `POST https://api.guidelab.co/integrations/xero/sync-invoice` Enqueue a single invoice for synchronization to Xero. Sets the invoice sync status to pending and adds it to the sync queue. Documentation: https://docs.guidelab.co/api-reference/integrations/syncXeroInvoice ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Invoice sync enqueued successfully with pending status - `success` (boolean) **(required)**: - `xeroSyncStatus` (string) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/xero/sync-invoice" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Sync a payment allocation to Xero `POST https://api.guidelab.co/integrations/xero/sync-payment` Replay or reconcile one payment allocation against the active Xero account. Documentation: https://docs.guidelab.co/api-reference/integrations/syncXeroPayment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Payment sync accepted - `success` (boolean) **(required)**: ### 400: Xero integration is not active ### 404: Payment allocation not found ### 409: Payment is bound elsewhere or retry budget exhausted ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/xero/sync-payment" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Xero sync logs `GET https://api.guidelab.co/integrations/xero/sync-log` Retrieve Xero synchronization log entries for the authenticated lab. Supports filtering by entity type and entity ID. Documentation: https://docs.guidelab.co/api-reference/integrations/listXeroSyncLogs ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of Xero sync log entries ordered by most recent first - `data` (array) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/xero/sync-log" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Twilio integration status `GET https://api.guidelab.co/integrations/twilio` Retrieve the current Twilio integration status and configuration for the authenticated lab. Auth tokens are masked in the response. Documentation: https://docs.guidelab.co/api-reference/integrations/getTwilioStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Twilio integration status and masked configuration - `platformNotificationsConfigured` (boolean): - `id` (string,null) **(required)**: - `isEnabled` (boolean) **(required)**: - `config` (object): ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/twilio" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Twilio integration settings `PUT https://api.guidelab.co/integrations/twilio` Create or update the Twilio integration settings including account credentials and phone numbers. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/updateTwilioIntegration ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `isEnabled` (boolean): - `config` (object): - `accountSid` (string): - `authToken` (object): - `whatsappNumber` (object): - `smsNumber` (object): ## Responses ### 200: Updated Twilio integration status and masked configuration - `platformNotificationsConfigured` (boolean): - `id` (string,null) **(required)**: - `isEnabled` (boolean) **(required)**: - `config` (object): ### 400: Invalid Twilio integration configuration ### 401: Unauthorized - valid session required ### 409: Stored Twilio integration configuration is invalid ## Example ```bash curl -X PUT "https://api.guidelab.co/integrations/twilio" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "isEnabled": true, "config": { "accountSid": "string", "authToken": "string", "whatsappNumber": "string", "smsNumber": "string" } }' ``` --- # Test Twilio API credentials `POST https://api.guidelab.co/integrations/twilio/test-connection` Verify Twilio API credentials by making a test call to the Twilio API. Returns whether the credentials are valid. Documentation: https://docs.guidelab.co/api-reference/integrations/testTwilioConnection ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `accountSid` (string) **(required)**: - `authToken` (string) **(required)**: ## Responses ### 200: Connection test result with validity status - `valid` (boolean) **(required)**: - `friendlyName` (string): - `status` (string): - `error` (string): ### 400: Invalid Twilio credentials ### 401: Unauthorized - valid session required ### 429: Twilio connection-test rate limit exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/twilio/test-connection" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "accountSid": "string", "authToken": "string" }' ``` --- # Send a test message via Twilio `POST https://api.guidelab.co/integrations/twilio/test-message` Queue an SMS test message through the authenticated lab's exact saved Twilio account and channel sender. Documentation: https://docs.guidelab.co/api-reference/integrations/sendTwilioTestMessage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `phoneNumber` (string) **(required)**: - `channel` (string): (default: `whatsapp`) Values: `whatsapp`, `sms` - `body` (string) **(required)**: ## Responses ### 200: Test message queue admission result - `success` (boolean) **(required)**: - `error` (string): ### 400: Invalid test-message request ### 401: Unauthorized - valid session required ### 409: Saved Twilio credentials or sender are unavailable ### 429: Paid test-message rate limit exceeded ### 503: Test-message queue or credentials temporarily unavailable ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/twilio/test-message" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "phoneNumber": "string", "channel": "whatsapp", "body": "string" }' ``` --- # Enable or disable Twilio inbound messages for the inbox `POST https://api.guidelab.co/integrations/twilio/inbox` Receive the saved Twilio SMS or WhatsApp sender in the lab inbox. SMS points the number's incoming-message URL at GuideLab (refusing to replace another URL unless overwriteWebhook is set); WhatsApp returns the URL to configure in Twilio. One account per channel: Meta WhatsApp and Twilio WhatsApp are mutually exclusive. Documentation: https://docs.guidelab.co/api-reference/integrations/configureTwilioInbox ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `channel` (string) **(required)**: Values: `sms`, `whatsapp` - `enabled` (boolean) **(required)**: - `overwriteWebhook` (boolean): ## Responses ### 200: The inbox connection and, for WhatsApp, its webhook URL - `connection` (object): - `webhookUrl` (string,null) **(required)**: ### 401: Unauthorized - valid session required ### 409: Twilio is not configured for the channel, the channel already has another account (channel_taken), or the number's webhook points elsewhere (webhook_in_use) ### 429: Channel connection limit reached ### 502: Twilio could not be reached ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/twilio/inbox" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "channel": "sms", "enabled": true, "overwriteWebhook": true }' ``` --- # Get Dentally connection status `GET https://api.guidelab.co/integrations/dentally` Retrieve the current Dentally connection status and configuration for the authenticated clinic. Documentation: https://docs.guidelab.co/api-reference/integrations/getDentallyConnection ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Dentally connection details or null if not configured - `id` (string) **(required)**: - `name` (string,null) **(required)**: - `apiBaseUrl` (string) **(required)**: - `connectionStatus` (string) **(required)**: - `statusMessage` (string,null) **(required)**: - `syncEnabled` (boolean) **(required)**: - `lastSyncAt` (string,null) **(required)**: - `lastSyncStatus` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/dentally" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Connect or update Dentally integration `POST https://api.guidelab.co/integrations/dentally` Create or update a Dentally connection for the authenticated clinic. Validates credentials before saving. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/connectDentally ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `apiKey` (string) **(required)**: - `apiBaseUrl` (string) **(required)**: Values: `https://api.dentally.co`, `https://api.apac.dentally.com`, `https://api.ca.dentally.com`, `https://api.sandbox.dentally.co` - `name` (string): (default: `Main Practice`) ## Responses ### 200: Created or updated Dentally connection details - `id` (string) **(required)**: - `name` (string,null) **(required)**: - `apiBaseUrl` (string) **(required)**: - `connectionStatus` (string) **(required)**: - `statusMessage` (string,null) **(required)**: - `syncEnabled` (boolean) **(required)**: - `lastSyncAt` (string,null) **(required)**: - `lastSyncStatus` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/dentally" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "apiKey": "string", "apiBaseUrl": "https://api.dentally.co", "name": "string" }' ``` --- # Disconnect Dentally integration `DELETE https://api.guidelab.co/integrations/dentally` Remove the Dentally connection for the authenticated clinic. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/disconnectDentally ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Dentally connection successfully removed - `success` (boolean) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X DELETE "https://api.guidelab.co/integrations/dentally" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Trigger Dentally patient sync `POST https://api.guidelab.co/integrations/dentally/sync` Trigger a patient sync from Dentally to the local database for the authenticated clinic. Documentation: https://docs.guidelab.co/api-reference/integrations/triggerDentallySync ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Sync result with counts of created, updated, and skipped patients - `id` (string) **(required)**: - `syncType` (string) **(required)**: - `status` (string) **(required)**: - `patientsCreated` (number) **(required)**: - `patientsUpdated` (number) **(required)**: - `patientsSkipped` (number) **(required)**: - `errorCount` (number) **(required)**: - `errors` (object): - `durationMs` (number,null) **(required)**: - `triggeredBy` (string,null) **(required)**: - `startedAt` (string) **(required)**: - `completedAt` (string,null) **(required)**: ### 401: Unauthorized - valid session required ### 429: Dentally sync rate limit exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/dentally/sync" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Dentally sync logs `GET https://api.guidelab.co/integrations/dentally/sync-logs` Retrieve recent Dentally patient sync log entries for the authenticated clinic. Documentation: https://docs.guidelab.co/api-reference/integrations/listDentallySyncLogs ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Array of sync log entries ordered by most recent first Array of: - `id` (string) **(required)**: - `syncType` (string) **(required)**: - `status` (string) **(required)**: - `patientsCreated` (number) **(required)**: - `patientsUpdated` (number) **(required)**: - `patientsSkipped` (number) **(required)**: - `errorCount` (number) **(required)**: - `errors` (object): - `durationMs` (number,null) **(required)**: - `triggeredBy` (string,null) **(required)**: - `startedAt` (string) **(required)**: - `completedAt` (string,null) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/dentally/sync-logs" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Test Dentally API credentials `POST https://api.guidelab.co/integrations/dentally/test` Test Dentally API credentials without saving them. Returns whether the connection is valid. Documentation: https://docs.guidelab.co/api-reference/integrations/testDentallyConnection ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `apiKey` (string) **(required)**: - `apiBaseUrl` (string) **(required)**: Values: `https://api.dentally.co`, `https://api.apac.dentally.com`, `https://api.ca.dentally.com`, `https://api.sandbox.dentally.co` ## Responses ### 200: Connection test result with validity status and message - `valid` (boolean) **(required)**: - `message` (string): ### 401: Unauthorized - valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/dentally/test" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "apiKey": "string", "apiBaseUrl": "https://api.dentally.co" }' ``` --- # Get Ariba integration status and configuration `GET https://api.guidelab.co/integrations/ariba` Retrieve the current SAP Ariba integration status and full configuration (connection, accounting, billing, automation) for the authenticated lab. Documentation: https://docs.guidelab.co/api-reference/integrations/getAribaStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Ariba integration status with masked secrets and full configuration - `id` (string,null) **(required)**: - `isEnabled` (boolean) **(required)**: - `config` (object) **(required)**: - `connection` (object): - `accounting` (object): - `billTo` (object): - `automation` (object): ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/ariba" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Ariba integration settings `PUT https://api.guidelab.co/integrations/ariba` Create or update the SAP Ariba integration settings including connection, accounting, billing, and automation configuration. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/updateAribaIntegration ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `isEnabled` (boolean): - `config` (object): - `connection` (object): - `deploymentMode` (string): Values: `test`, `production` - `senderNetworkId` (object): - `recipientNetworkId` (object): - `sharedSecret` (object): - `endpointUrl` (object): - `contractNumber` (object): - `accounting` (object): - `company` (object): - `percentage` (object): - `businessUnit` (object): - `costCentre` (object): - `procurementUnit` (object): - `account` (object): - `billTo` (object): - `addressId` (object): - `name` (object): - `street` (object): - `city` (object): - `state` (object): - `postalCode` (object): - `country` (object): - `automation` (object): - `autoSendXml` (boolean): - `clinicIds` (string[]): ## Responses ### 200: Updated Ariba integration status and configuration - `id` (string,null) **(required)**: - `isEnabled` (boolean) **(required)**: - `config` (object) **(required)**: - `connection` (object): - `accounting` (object): - `billTo` (object): - `automation` (object): ### 400: Invalid request body ### 401: Unauthorized - valid session required ### 409: Stored integration configuration is invalid ## Example ```bash curl -X PUT "https://api.guidelab.co/integrations/ariba" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "isEnabled": true, "config": { "connection": { "deploymentMode": "test", "senderNetworkId": "string", "recipientNetworkId": "string", "sharedSecret": "string", "endpointUrl": "string", "contractNumber": "string" }, "accounting": { "company": "string", "percentage": "string", "businessUnit": "string", "costCentre": "string", "procurementUnit": "string", "account": "string" }, "billTo": {}, "automation": { "autoSendXml": true, "clinicIds": [ "string" ] } } }' ``` --- # Preview Ariba cXML invoice `GET https://api.guidelab.co/integrations/ariba/preview-cxml` Preview the frozen, secret-masked supplier-direct contract invoice for a selected partner clinic. Documentation: https://docs.guidelab.co/api-reference/integrations/previewAribaCxml ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `invoiceId` (string) **(required)** (in: query): ## Responses ### 200: Masked cXML invoice - `cxml` (string) **(required)**: ### 400: Invoice or configuration ineligible ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/ariba/preview-cxml" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Queue invoice for Ariba `POST https://api.guidelab.co/integrations/ariba/send-invoice` Reserve one immutable invoice transmission and queue it. Queue acceptance is distinct from SAP cXML acknowledgement. Requires manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/sendAribaInvoice ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `invoiceId` (string) **(required)**: ## Responses ### 200: Existing operation - `success` (boolean) **(required)**: - `statusCode` (integer) **(required)**: - `response` (string) **(required)**: - `queued` (boolean) **(required)**: - `operation` (object) **(required)**: - `id` (string) **(required)**: - `invoiceId` (string) **(required)**: - `status` (string) **(required)**: Values: `pending`, `processing`, `retry`, `accepted`, `rejected`, `needs_review`, `failed`, `cancelled` - `attempts` (integer) **(required)**: - `statusCode` (integer,null) **(required)**: - `errorCode` (string,null) **(required)**: - `updatedAt` (string) **(required)**: ### 202: Transmission queued - `success` (boolean) **(required)**: - `statusCode` (integer) **(required)**: - `response` (string) **(required)**: - `queued` (boolean) **(required)**: - `operation` (object) **(required)**: - `id` (string) **(required)**: - `invoiceId` (string) **(required)**: - `status` (string) **(required)**: Values: `pending`, `processing`, `retry`, `accepted`, `rejected`, `needs_review`, `failed`, `cancelled` - `attempts` (integer) **(required)**: - `statusCode` (integer,null) **(required)**: - `errorCode` (string,null) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invoice or configuration ineligible ### 401: Unauthorized ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/ariba/send-invoice" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "invoiceId": "string" }' ``` --- # Get Ariba invoice transmission status `GET https://api.guidelab.co/integrations/ariba/invoice-status` Documentation: https://docs.guidelab.co/api-reference/integrations/getAribaInvoiceStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `invoiceId` (string) **(required)** (in: query): ## Responses ### 200: Operation and current eligibility - `operation` (object,null) **(required)**: - `id` (string) **(required)**: - `invoiceId` (string) **(required)**: - `status` (string) **(required)**: Values: `pending`, `processing`, `retry`, `accepted`, `rejected`, `needs_review`, `failed`, `cancelled` - `attempts` (integer) **(required)**: - `statusCode` (integer,null) **(required)**: - `errorCode` (string,null) **(required)**: - `updatedAt` (string) **(required)**: - `eligible` (boolean) **(required)**: ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/ariba/invoice-status" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List active partner clinics for Ariba selection `GET https://api.guidelab.co/integrations/ariba/clinics` Documentation: https://docs.guidelab.co/api-reference/integrations/getAribaEligibleClinics ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` ## Responses ### 200: One bounded page of eligible partner clinics - `clinics` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `hasMore` (boolean) **(required)**: ### 401: Unauthorized ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/ariba/clinics" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Read imported exocad design metadata `GET https://api.guidelab.co/integrations/exocad/orders/:orderId/constructions` Documentation: https://docs.guidelab.co/api-reference/integrations/getExocadOrderConstructions ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `orderId` (string) **(required)** (in: path): - `cursor` (string) (in: query): ## Responses ### 200: A bounded page of construction metadata; catalogue mappings never change billing - `constructions` (object[]) **(required)**: - `id` (string) **(required)**: - `fileId` (string) **(required)**: - `filename` (string) **(required)**: - `projectName` (string,null) **(required)**: - `partType` (string,null) **(required)**: - `material` (string,null) **(required)**: - `materialName` (string,null) **(required)**: - `resolvedMaterialName` (string,null) **(required)**: - `teeth` (object[]) **(required)**: - `toothNumber` (integer) **(required)**: - `reconstructionType` (string,null) **(required)**: - `cutbackPerformed` (boolean,null) **(required)**: - `shade` (string,null) **(required)**: - `resolvedProductId` (string,null) **(required)**: - `resolvedProductName` (string,null) **(required)**: - `nextCursor` (string,null) **(required)**: ### 401: Unauthorized ### 403: Lab membership required ### 404: Order not found ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/exocad/orders/:orderId/constructions" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get exocad integration status and mappings `GET https://api.guidelab.co/integrations/exocad` Retrieve the current exocad integration status, configuration, and all material/reconstruction type mappings for the authenticated lab. Documentation: https://docs.guidelab.co/api-reference/integrations/getExocadStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Exocad integration status with configuration and mappings - `id` (string,null) **(required)**: - `isEnabled` (boolean) **(required)**: - `config` (object) **(required)**: - `autoGenerateDentalProject` (boolean): (default: `false`) - `fileNamingTemplate` (string): (default: `{{LOCATION_NAME}}-{{ORDER_NUMBER}}`) - `autoAssignEnabled` (boolean): (default: `false`) - `assignmentOnImportEnabled` (boolean): (default: `false`) - `autoAssignMode` (string): (default: `specific_member`) Values: `specific_member`, `round_robin` - `defaultAssigneeId` (string,null): (default: `null`) - `roundRobinMemberIds` (string[]): (default: ``) - `lastRoundRobinIndex` (integer): (default: `0`) - `reconstructionMappings` (object[]) **(required)**: - `id` (string) **(required)**: - `exocadType` (string) **(required)**: - `productId` (string,null) **(required)**: - `materialMappings` (object[]) **(required)**: - `id` (string) **(required)**: - `exocadMaterial` (string) **(required)**: - `materialId` (string,null) **(required)**: ### 401: Unauthorized - valid session required ### 409: Stored Exocad mapping capacity is invalid ### 500: Stored configuration is invalid, or internal error ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/exocad" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete exocad integration `DELETE https://api.guidelab.co/integrations/exocad` Remove the exocad integration and every stored mapping for the authenticated lab. Disabling only clears the enabled flag; this is the one way to discard mapping rows whose exocad code is no longer offered. Documentation: https://docs.guidelab.co/api-reference/integrations/deleteExocadIntegration ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Exocad integration removed - `deleted` (boolean) **(required)**: ### 401: Unauthorized - valid session required ### 404: Exocad integration not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/integrations/exocad" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update exocad integration settings `PUT https://api.guidelab.co/integrations/exocad` Create or update the exocad integration settings including folder paths and auto-import configuration for the authenticated lab. Documentation: https://docs.guidelab.co/api-reference/integrations/updateExocadIntegration ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `isEnabled` (boolean): - `config` (object): - `autoGenerateDentalProject` (boolean): - `fileNamingTemplate` (string): - `autoAssignEnabled` (boolean): - `assignmentOnImportEnabled` (boolean): - `autoAssignMode` (string): Values: `specific_member`, `round_robin` - `defaultAssigneeId` (string,null): - `roundRobinMemberIds` (string[]): ## Responses ### 200: Updated exocad integration record - `integration` (object) **(required)**: - `id` (string,null) **(required)**: - `isEnabled` (boolean) **(required)**: - `config` (object) **(required)**: - `autoGenerateDentalProject` (boolean): (default: `false`) - `fileNamingTemplate` (string): (default: `{{LOCATION_NAME}}-{{ORDER_NUMBER}}`) - `autoAssignEnabled` (boolean): (default: `false`) - `assignmentOnImportEnabled` (boolean): (default: `false`) - `autoAssignMode` (string): (default: `specific_member`) Values: `specific_member`, `round_robin` - `defaultAssigneeId` (string,null): (default: `null`) - `roundRobinMemberIds` (string[]): (default: ``) - `lastRoundRobinIndex` (integer): (default: `0`) ### 400: Invalid integration configuration ### 401: Unauthorized - valid session required ### 409: Stored integration configuration is invalid ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/integrations/exocad" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "isEnabled": true, "config": {} }' ``` --- # Update exocad material mappings `PUT https://api.guidelab.co/integrations/exocad/material-mappings` Update the mapping between exocad material names and local material records for the authenticated lab. Documentation: https://docs.guidelab.co/api-reference/integrations/updateExocadMaterialMappings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `mappings` (object[]) **(required)**: - `exocadMaterial` (string) **(required)**: - `materialId` (string,null) **(required)**: ## Responses ### 200: Updated list of exocad material mappings - `mappings` (object[]) **(required)**: - `id` (string) **(required)**: - `exocadMaterial` (string) **(required)**: - `materialId` (string,null) **(required)**: ### 400: Invalid material IDs ### 401: Unauthorized - valid session required ### 404: Exocad integration not found ### 409: Exocad mapping capacity reached ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/integrations/exocad/material-mappings" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "mappings": [ { "exocadMaterial": "string", "materialId": "string" } ] }' ``` --- # Update exocad reconstruction type mappings `PUT https://api.guidelab.co/integrations/exocad/reconstruction-mappings` Update the mapping between exocad reconstruction types and local product records for the authenticated lab. Documentation: https://docs.guidelab.co/api-reference/integrations/updateExocadReconstructionMappings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `mappings` (object[]) **(required)**: - `exocadType` (string) **(required)**: - `productId` (string,null) **(required)**: ## Responses ### 200: Updated list of exocad reconstruction type mappings - `mappings` (object[]) **(required)**: - `id` (string) **(required)**: - `exocadType` (string) **(required)**: - `productId` (string,null) **(required)**: ### 400: Invalid product IDs ### 401: Unauthorized - valid session required ### 404: Exocad integration not found ### 409: Exocad mapping capacity reached ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/integrations/exocad/reconstruction-mappings" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "mappings": [ { "exocadType": "string", "productId": "string" } ] }' ``` --- # Get Bite Finder integration status `GET https://api.guidelab.co/integrations/bite-finder` Retrieve the current Bite Finder integration status and configuration for the authenticated lab. Documentation: https://docs.guidelab.co/api-reference/integrations/getBiteFinderStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Bite Finder integration status and masked configuration - `id` (string,null) **(required)**: - `isEnabled` (boolean) **(required)**: - `connectionStatus` (string,null) **(required)**: - `statusMessage` (string,null) **(required)**: - `config` (object) **(required)**: - `apiKey` (string) **(required)**: - `processing` (object) **(required)**: ### 401: Unauthorized - valid session required ### 403: Forbidden - lab organization required ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/bite-finder" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Bite Finder integration settings `PUT https://api.guidelab.co/integrations/bite-finder` Create or update the Bite Finder integration settings for the authenticated lab. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/updateBiteFinderIntegration ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `isEnabled` (boolean): - `config` (object): - `apiKey` (string): - `processing` (object): - `bundle` (string) **(required)**: Values: `quality_check`, `static_occlusion`, `static_dynamic_occlusion`, `static_dynamic_occlusion_printable` - `maximalPenetration` (number) **(required)**: - `staticReturnType` (string) **(required)**: Values: `Mesh`, `MeshAndBite`, `Transformation` - `dynamicFormat` (string) **(required)**: Values: `XML`, `Jawmotion` - `segmentation` (boolean) **(required)**: - `occlusionRenderings` (boolean) **(required)**: - `pdfReport` (boolean) **(required)**: - `launcherFiles` (boolean) **(required)**: - `executionPolicy` (object) **(required)**: - `active` (boolean) **(required)**: - `fullArchSkipAbove` (number) **(required)**: - `fullArchRefundBelow` (number) **(required)**: - `quadrantSkipAbove` (number) **(required)**: - `quadrantRefundBelow` (number) **(required)**: ## Responses ### 200: Updated Bite Finder integration status and masked configuration - `id` (string,null) **(required)**: - `isEnabled` (boolean) **(required)**: - `connectionStatus` (string,null) **(required)**: - `statusMessage` (string,null) **(required)**: - `config` (object) **(required)**: - `apiKey` (string) **(required)**: - `processing` (object) **(required)**: ### 400: Invalid request body ### 401: Unauthorized - valid session required ### 403: Forbidden - lab manager access required ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/integrations/bite-finder" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "isEnabled": true, "config": { "apiKey": "string", "processing": { "bundle": "quality_check", "maximalPenetration": 0, "staticReturnType": "Mesh", "dynamicFormat": "XML", "segmentation": true, "occlusionRenderings": true, "pdfReport": true, "launcherFiles": true, "executionPolicy": { "active": true, "fullArchSkipAbove": 0, "fullArchRefundBelow": 0, "quadrantSkipAbove": 0, "quadrantRefundBelow": 0 } } } }' ``` --- # Test the Bite Finder connection `POST https://api.guidelab.co/integrations/bite-finder/test-connection` Verify the stored Bite Finder credential against the provider. Uses an unmetered status probe and never creates a case. Documentation: https://docs.guidelab.co/api-reference/integrations/testBiteFinderConnection ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Probe result - `ok` (boolean) **(required)**: - `connectionStatus` (string) **(required)**: - `statusMessage` (string,null) **(required)**: ### 400: No stored credential to test ### 401: Unauthorized - valid session required ### 403: Forbidden - lab manager access required ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/bite-finder/test-connection" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Bite Finder cases for an order `GET https://api.guidelab.co/integrations/bite-finder/cases` List this lab's Bite-Finder cases for one order. Documentation: https://docs.guidelab.co/api-reference/integrations/listBiteFinderCases ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `orderId` (string) **(required)** (in: query): ## Responses ### 200: Cases for the order, newest first - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `status` (string) **(required)**: Values: `pending`, `uploading`, `processing`, `downloading`, `succeeded`, `skipped`, `failed` - `orderId` (string) **(required)**: - `fileType` (string) **(required)**: - `executionPolicyStatus` (string,null) **(required)**: - `lastError` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `completedAt` (string,null) **(required)**: ### 401: Unauthorized - valid session required ### 403: Forbidden - lab organization required ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/bite-finder/cases" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Send an order to Bite Finder `POST https://api.guidelab.co/integrations/bite-finder/cases` Submit an order's upper and lower jaw meshes to Bite-Finder. Spends one Bite-Finder credit; re-submitting the same order and meshes returns the existing case instead. Documentation: https://docs.guidelab.co/api-reference/integrations/createBiteFinderCase ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `orderId` (string) **(required)**: - `upperFileId` (string) **(required)**: - `lowerFileId` (string) **(required)**: ## Responses ### 200: The existing case for these meshes - `id` (string) **(required)**: - `status` (string) **(required)**: Values: `pending`, `uploading`, `processing`, `downloading`, `succeeded`, `skipped`, `failed` - `orderId` (string) **(required)**: - `fileType` (string) **(required)**: - `executionPolicyStatus` (string,null) **(required)**: - `lastError` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `completedAt` (string,null) **(required)**: ### 201: Case queued - `id` (string) **(required)**: - `status` (string) **(required)**: Values: `pending`, `uploading`, `processing`, `downloading`, `succeeded`, `skipped`, `failed` - `orderId` (string) **(required)**: - `fileType` (string) **(required)**: - `executionPolicyStatus` (string,null) **(required)**: - `lastError` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `completedAt` (string,null) **(required)**: ### 400: Invalid request or unusable source meshes ### 401: Unauthorized - valid session required ### 403: Forbidden - lab manager access required ### 404: Order not found for this lab ### 429: Bite Finder case budget exhausted ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/bite-finder/cases" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "orderId": "string", "upperFileId": "string", "lowerFileId": "string" }' ``` --- # Get HeyGears integration status `GET https://api.guidelab.co/integrations/heygears` Retrieve the current HeyGears integration status and configuration for the authenticated lab. Documentation: https://docs.guidelab.co/api-reference/integrations/getHeyGearsStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: HeyGears integration status and masked configuration - `id` (string,null) **(required)**: - `isEnabled` (boolean) **(required)**: - `config` (object) **(required)**: - `apiKey` (string) **(required)**: - `endpointUrl` (string) **(required)**: ### 401: Unauthorized - valid session required ### 403: Forbidden - lab organization required ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/heygears" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update HeyGears integration settings `PUT https://api.guidelab.co/integrations/heygears` Create or update the HeyGears integration settings for the authenticated lab. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/updateHeyGearsIntegration ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `isEnabled` (boolean): - `config` (object): - `apiKey` (string): - `endpointUrl` (object): ## Responses ### 200: Updated HeyGears integration status and masked configuration - `id` (string,null) **(required)**: - `isEnabled` (boolean) **(required)**: - `config` (object) **(required)**: - `apiKey` (string) **(required)**: - `endpointUrl` (string) **(required)**: ### 400: Invalid request body ### 401: Unauthorized - valid session required ### 403: Forbidden - lab manager access required ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/integrations/heygears" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "isEnabled": true, "config": { "apiKey": "string", "endpointUrl": "string" } }' ``` --- # Get ShipStation partner shipping status `GET https://api.guidelab.co/integrations/ship-engine` Documentation: https://docs.guidelab.co/api-reference/integrations/getShipEngineIntegration ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Shipping integration status ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/ship-engine" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Provision the lab's ShipStation partner sub-account `POST https://api.guidelab.co/integrations/ship-engine/provision` Documentation: https://docs.guidelab.co/api-reference/integrations/provisionShipEngineIntegration ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `originCountryCode` (string) **(required)**: Values: `GB`, `IT` ## Responses ### 200: Existing connected account ### 201: Sub-account and tracking webhook provisioned ### 202: A bounded provisioning attempt is already in progress ### 400: Unsupported or mismatched origin country ### 403: Organization manager access required ### 429: Provider operation budget exhausted ### 502: Provider setup failed safely ### 503: Provider integration is disabled ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/ship-engine/provision" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "originCountryCode": "GB" }' ``` --- # List the lab's connected carrier accounts `GET https://api.guidelab.co/integrations/ship-engine/carriers` Documentation: https://docs.guidelab.co/api-reference/integrations/listShipEngineCarriers ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Bounded carrier list ### 409: Shipping provider is not connected ### 429: Provider operation budget exhausted ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/ship-engine/carriers" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Connect a lab-owned carrier account without retaining its credentials `POST https://api.guidelab.co/integrations/ship-engine/carriers` Documentation: https://docs.guidelab.co/api-reference/integrations/connectShipEngineCarrier ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `carrierName` (string) **(required)**: - `credentials` (object) **(required)**: ## Responses ### 201: Carrier account connected ### 409: Shipping provider is not connected ### 429: Provider operation budget exhausted ### 502: Carrier connection rejected ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/ship-engine/carriers" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "carrierName": "string", "credentials": {} }' ``` --- # Get a lab financial document's Fatture in Cloud export and SDI status `GET https://api.guidelab.co/integrations/fatture-in-cloud/document-status` Documentation: https://docs.guidelab.co/api-reference/integrations/getFattureInCloudDocumentStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `invoiceId` (string) (in: query): - `creditNoteId` (string) (in: query): ## Responses ### 200: Status in the currently connected accounting company - `syncStatus` (string) **(required)**: - `eiStatus` (string) **(required)**: - `providerDocumentId` (string,null) **(required)**: - `fiscalNumber` (number,null) **(required)**: - `fiscalNumeration` (string,null) **(required)**: - `sdiEnabled` (boolean) **(required)**: - `canManage` (boolean) **(required)**: ### 404: Financial document not found ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/fatture-in-cloud/document-status" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Fatture in Cloud integration status `GET https://api.guidelab.co/integrations/fatture-in-cloud` Retrieve the current Fatture in Cloud integration status, connection state, and configuration for the authenticated lab. Documentation: https://docs.guidelab.co/api-reference/integrations/getFattureInCloudStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Fatture in Cloud integration status including connection state and settings - `paymentImportBlocked` (boolean): - `id` (string,null) **(required)**: - `isEnabled` (boolean) **(required)**: - `connectionState` (string) **(required)**: Values: `disconnected`, `pending_company_selection`, `connected`, `needs_reauthorization` - `companyName` (string,null) **(required)**: - `config` (object) **(required)**: - `numeration` (string) **(required)**: - `defaultVatTypeId` (integer,null) **(required)**: - `vatTypeIdsByRate` (object) **(required)**: - `stampDutyVatTypeId` (integer,null) **(required)**: - `paymentAccountId` (integer,null) **(required)**: - `paymentMethodId` (integer,null) **(required)**: - `autoSyncOnSend` (boolean) **(required)**: - `autoSyncPayments` (boolean) **(required)**: - `sdiEnabled` (boolean) **(required)**: - `sdiPaymentMethod` (string,null) **(required)**: - `taxRatesInUse` (string[]): ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/fatture-in-cloud" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Fatture in Cloud integration settings `PUT https://api.guidelab.co/integrations/fatture-in-cloud` Update Fatture in Cloud integration settings such as numeration, default VAT type, payment account/method, sync preferences, and the SDI toggle. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/updateFattureInCloudSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Updated Fatture in Cloud integration status and configuration - `paymentImportBlocked` (boolean): - `id` (string,null) **(required)**: - `isEnabled` (boolean) **(required)**: - `connectionState` (string) **(required)**: Values: `disconnected`, `pending_company_selection`, `connected`, `needs_reauthorization` - `companyName` (string,null) **(required)**: - `config` (object) **(required)**: - `numeration` (string) **(required)**: - `defaultVatTypeId` (integer,null) **(required)**: - `vatTypeIdsByRate` (object) **(required)**: - `stampDutyVatTypeId` (integer,null) **(required)**: - `paymentAccountId` (integer,null) **(required)**: - `paymentMethodId` (integer,null) **(required)**: - `autoSyncOnSend` (boolean) **(required)**: - `autoSyncPayments` (boolean) **(required)**: - `sdiEnabled` (boolean) **(required)**: - `sdiPaymentMethod` (string,null) **(required)**: - `taxRatesInUse` (string[]): ### 401: Unauthorized - valid session required ## Example ```bash curl -X PUT "https://api.guidelab.co/integrations/fatture-in-cloud" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Initiate Fatture in Cloud OAuth authorization `POST https://api.guidelab.co/integrations/fatture-in-cloud/authorize` Initiate the Fatture in Cloud OAuth 2.0 authorization flow. Returns a URL to redirect the user to the consent screen. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/initiateFattureInCloudOAuth ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Fatture in Cloud OAuth consent URL to redirect the user to - `url` (string) **(required)**: ### 401: Unauthorized - valid session required ### 403: Organization manager access required ### 409: The organization currency is not EUR (code: currency_not_supported) ### 503: Fatture in Cloud OAuth is not configured ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/fatture-in-cloud/authorize" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Handle Fatture in Cloud OAuth callback `GET https://api.guidelab.co/integrations/fatture-in-cloud/callback` Handle the Fatture in Cloud OAuth 2.0 callback. Exchanges the authorization code for tokens, and either binds the single visible company or parks the grant until a manager selects one. Documentation: https://docs.guidelab.co/api-reference/integrations/handleFattureInCloudOAuthCallback ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 302: Redirect back to the integration settings page carrying the connection status in the fatture_in_cloud query parameter ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/fatture-in-cloud/callback" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Fatture in Cloud companies `GET https://api.guidelab.co/integrations/fatture-in-cloud/companies` List the Fatture in Cloud companies visible to the pending grant so a manager can select exactly one. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/listFattureInCloudCompanies ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Companies available to the pending authorization - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `vatNumber` (string,null) **(required)**: - `taxCode` (string,null) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/fatture-in-cloud/companies" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Select the Fatture in Cloud company `POST https://api.guidelab.co/integrations/fatture-in-cloud/select-company` Bind the pending Fatture in Cloud grant to exactly one company, activating the integration. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/selectFattureInCloudCompany ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Company bound and integration activated - `success` (boolean) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/fatture-in-cloud/select-company" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Disconnect Fatture in Cloud integration `POST https://api.guidelab.co/integrations/fatture-in-cloud/disconnect` Disconnect the Fatture in Cloud integration by revoking the OAuth grant while preserving configuration settings. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/disconnectFattureInCloud ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Fatture in Cloud integration successfully disconnected - `success` (boolean) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/fatture-in-cloud/disconnect" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Fatture in Cloud VAT types `GET https://api.guidelab.co/integrations/fatture-in-cloud/vat-types` Fetch VAT types from the connected Fatture in Cloud company for settings configuration. Owner/admin only; provider access may idempotently refresh and persist an expired OAuth token. Documentation: https://docs.guidelab.co/api-reference/integrations/listFattureInCloudVatTypes ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of VAT types with id, percentage, and description - `data` (object[]) **(required)**: - `id` (number) **(required)**: - `value` (number) **(required)**: - `description` (string,null) **(required)**: - `eiType` (string,null) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/fatture-in-cloud/vat-types" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Fatture in Cloud payment accounts `GET https://api.guidelab.co/integrations/fatture-in-cloud/payment-accounts` Fetch payment accounts from the connected Fatture in Cloud company for settings configuration. Owner/admin only; provider access may idempotently refresh and persist an expired OAuth token. Documentation: https://docs.guidelab.co/api-reference/integrations/listFattureInCloudPaymentAccounts ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of payment accounts with id, name, and type - `data` (object[]) **(required)**: - `id` (number) **(required)**: - `name` (string) **(required)**: - `type` (string,null) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/fatture-in-cloud/payment-accounts" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Fatture in Cloud payment methods `GET https://api.guidelab.co/integrations/fatture-in-cloud/payment-methods` Fetch payment methods from the connected Fatture in Cloud company for settings configuration. Owner/admin only; provider access may idempotently refresh and persist an expired OAuth token. Documentation: https://docs.guidelab.co/api-reference/integrations/listFattureInCloudPaymentMethods ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of payment methods with id and name - `data` (object[]) **(required)**: - `id` (number) **(required)**: - `name` (string) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/fatture-in-cloud/payment-methods" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Search Fatture in Cloud clients `GET https://api.guidelab.co/integrations/fatture-in-cloud/clients/search` Search for clients in the connected Fatture in Cloud company while configuring mappings. Owner/admin only; provider access may idempotently refresh and persist an expired OAuth token. Requires a minimum 2-character query. Documentation: https://docs.guidelab.co/api-reference/integrations/searchFattureInCloudClients ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of matching clients with id, name, VAT number, and tax code - `data` (object[]) **(required)**: - `clientId` (string) **(required)**: - `name` (string) **(required)**: - `vatNumber` (string,null) **(required)**: - `taxCode` (string,null) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/fatture-in-cloud/clients/search" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Fatture in Cloud client mappings `GET https://api.guidelab.co/integrations/fatture-in-cloud/client-mappings` Retrieve all clinic-to-Fatture in Cloud client mappings for the authenticated lab. Documentation: https://docs.guidelab.co/api-reference/integrations/listFattureInCloudClientMappings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of clinic-to-client mappings with match method - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `partnershipId` (string) **(required)**: - `clinicId` (string) **(required)**: - `clinicName` (string) **(required)**: - `providerClientId` (string) **(required)**: - `providerClientName` (string) **(required)**: - `vatNumber` (string,null) **(required)**: - `taxCode` (string,null) **(required)**: - `matchMethod` (string) **(required)**: - `updatedAt` (string,null) **(required)**: [date-time] ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/fatture-in-cloud/client-mappings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Fatture in Cloud client mapping `DELETE https://api.guidelab.co/integrations/fatture-in-cloud/client-mappings` Remove a clinic-to-Fatture in Cloud client mapping by clinic ID. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/deleteFattureInCloudClientMapping ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Client mapping successfully deleted - `success` (boolean) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X DELETE "https://api.guidelab.co/integrations/fatture-in-cloud/client-mappings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upsert Fatture in Cloud client mapping `PUT https://api.guidelab.co/integrations/fatture-in-cloud/client-mappings` Create or update a mapping between a partner clinic and a Fatture in Cloud client for document synchronization. Requires organization manager access. Documentation: https://docs.guidelab.co/api-reference/integrations/upsertFattureInCloudClientMapping ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Client mapping successfully created or updated - `success` (boolean) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X PUT "https://api.guidelab.co/integrations/fatture-in-cloud/client-mappings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Sync an invoice to Fatture in Cloud `POST https://api.guidelab.co/integrations/fatture-in-cloud/sync-invoice` Enqueue a single invoice for export to Fatture in Cloud. The provider assigns the fiscal number inside the configured numeration. Documentation: https://docs.guidelab.co/api-reference/integrations/syncFattureInCloudInvoice ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Invoice export enqueued successfully - `success` (boolean) **(required)**: - `syncStatus` (string) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/fatture-in-cloud/sync-invoice" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Sync a credit note to Fatture in Cloud `POST https://api.guidelab.co/integrations/fatture-in-cloud/sync-credit-note` Enqueue a single credit note for export to Fatture in Cloud, or replay one that reached a terminal state. Documentation: https://docs.guidelab.co/api-reference/integrations/syncFattureInCloudCreditNote ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Credit note export enqueued successfully - `success` (boolean) **(required)**: - `syncStatus` (string) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/fatture-in-cloud/sync-credit-note" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Reconcile invoice payments to Fatture in Cloud `POST https://api.guidelab.co/integrations/fatture-in-cloud/sync-payments` Reconcile the embedded payment schedule of one exported invoice against the connected Fatture in Cloud company. Documentation: https://docs.guidelab.co/api-reference/integrations/syncFattureInCloudPayments ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Payment reconciliation accepted - `success` (boolean) **(required)**: ### 400: Fatture in Cloud integration is not active ### 409: Invoice is not exported or retry budget exhausted ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/fatture-in-cloud/sync-payments" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Send an invoice to SDI `POST https://api.guidelab.co/integrations/fatture-in-cloud/send-e-invoice` Explicitly submit one exported invoice or credit note to SDI through Fatture in Cloud after verification. SDI submission is a legal act: it only ever happens through this manager-confirmed action, never automatically. Documentation: https://docs.guidelab.co/api-reference/integrations/sendFattureInCloudEInvoice ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` ## Responses ### 200: SDI submission enqueued - `success` (boolean) **(required)**: ### 400: Fatture in Cloud integration is not active ### 409: SDI is not enabled, the invoice is not exported, or the send already happened ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/fatture-in-cloud/send-e-invoice" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '"string"' ``` --- # Refresh an invoice's SDI status `POST https://api.guidelab.co/integrations/fatture-in-cloud/refresh-e-invoice-status` Fetch the canonical SDI status of one exported invoice or credit note from Fatture in Cloud and store it. Documentation: https://docs.guidelab.co/api-reference/integrations/refreshFattureInCloudEInvoiceStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` ## Responses ### 200: Status refresh enqueued - `success` (boolean) **(required)**: ### 400: Fatture in Cloud integration is not active ### 409: Invoice is not exported ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/fatture-in-cloud/refresh-e-invoice-status" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '"string"' ``` --- # List Fatture in Cloud sync logs `GET https://api.guidelab.co/integrations/fatture-in-cloud/sync-log` Retrieve Fatture in Cloud synchronization log entries for the authenticated lab, including fiscal numbers and SDI status. Supports filtering by entity type and entity ID. Documentation: https://docs.guidelab.co/api-reference/integrations/listFattureInCloudSyncLogs ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of sync log entries ordered by most recent first - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `fattureInCloudAccountId` (string) **(required)**: - `entityType` (string) **(required)**: - `entityId` (string,null) **(required)**: - `invoiceId` (string,null) **(required)**: - `creditNoteId` (string,null) **(required)**: - `action` (string) **(required)**: - `phase` (string) **(required)**: - `status` (string) **(required)**: - `documentSyncStatus` (string) **(required)**: - `providerAttempts` (integer) **(required)**: - `attemptNumber` (integer) **(required)**: - `providerEntityId` (string,null) **(required)**: - `lastError` (string,null) **(required)**: - `errorMessage` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `fiscalNumber` (integer,null) **(required)**: - `fiscalNumeration` (string,null) **(required)**: - `fiscalYear` (integer,null) **(required)**: - `eiStatus` (string) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/fatture-in-cloud/sync-log" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List inbox channel connections and which channels can connect `GET https://api.guidelab.co/integrations/channels` Documentation: https://docs.guidelab.co/api-reference/integrations/listInboxChannels ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Connections and platform availability - `connections` (object[]) **(required)**: - `id` (string) **(required)**: - `provider` (string) **(required)**: Values: `meta_whatsapp`, `twilio`, `telegram`, `meta_messaging`, `gmail`, `microsoft365` - `channel` (string) **(required)**: Values: `whatsapp`, `sms`, `telegram`, `messenger`, `instagram`, `email` - `address` (string,null) **(required)**: - `status` (string) **(required)**: Values: `pending`, `active`, `error`, `disconnected` - `statusMessage` (string,null) **(required)**: - `lastInboundAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `availability` (object) **(required)**: - `metaWhatsApp` (object,null) **(required)**: - `appId` (string) **(required)**: - `configId` (string) **(required)**: - `graphVersion` (string) **(required)**: - `metaMessaging` (boolean) **(required)**: - `telegram` (boolean) **(required)**: - `gmail` (boolean) **(required)**: - `outlook` (boolean) **(required)**: - `twilio` (boolean) **(required)**: ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/channels" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Connect a WhatsApp number from Meta Embedded Signup `POST https://api.guidelab.co/integrations/meta-whatsapp/embedded-signup` Documentation: https://docs.guidelab.co/api-reference/integrations/completeWhatsAppEmbeddedSignup ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `code` (string) **(required)**: - `wabaId` (string) **(required)**: - `phoneNumberId` (string) **(required)**: ## Responses ### 200: The connection - `connection` (object) **(required)**: - `id` (string) **(required)**: - `provider` (string) **(required)**: Values: `meta_whatsapp`, `twilio`, `telegram`, `meta_messaging`, `gmail`, `microsoft365` - `channel` (string) **(required)**: Values: `whatsapp`, `sms`, `telegram`, `messenger`, `instagram`, `email` - `address` (string,null) **(required)**: - `status` (string) **(required)**: Values: `pending`, `active`, `error`, `disconnected` - `statusMessage` (string,null) **(required)**: - `lastInboundAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: ### 400: Request could not be completed - `error` (string) **(required)**: ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ### 409: Request could not be completed - `error` (string) **(required)**: ### 429: Request could not be completed - `error` (string) **(required)**: ### 502: Request could not be completed - `error` (string) **(required)**: ### 503: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/meta-whatsapp/embedded-signup" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "code": "string", "wabaId": "string", "phoneNumberId": "string" }' ``` --- # Finish a WhatsApp connection (optionally with the number's PIN) `POST https://api.guidelab.co/integrations/meta-whatsapp/connections/{id}/resume` Documentation: https://docs.guidelab.co/api-reference/integrations/resumeWhatsAppConnection ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `pin` (string): ## Responses ### 200: The connection - `connection` (object) **(required)**: - `id` (string) **(required)**: - `provider` (string) **(required)**: Values: `meta_whatsapp`, `twilio`, `telegram`, `meta_messaging`, `gmail`, `microsoft365` - `channel` (string) **(required)**: Values: `whatsapp`, `sms`, `telegram`, `messenger`, `instagram`, `email` - `address` (string,null) **(required)**: - `status` (string) **(required)**: Values: `pending`, `active`, `error`, `disconnected` - `statusMessage` (string,null) **(required)**: - `lastInboundAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ### 404: Request could not be completed - `error` (string) **(required)**: ### 409: Request could not be completed - `error` (string) **(required)**: ### 429: Request could not be completed - `error` (string) **(required)**: ### 502: Request could not be completed - `error` (string) **(required)**: ### 503: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/meta-whatsapp/connections/{id}/resume" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "pin": "string" }' ``` --- # Disconnect a WhatsApp number from the inbox `POST https://api.guidelab.co/integrations/meta-whatsapp/connections/{id}/disconnect` Documentation: https://docs.guidelab.co/api-reference/integrations/disconnectWhatsAppConnection ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Disconnected - `ok` (boolean) **(required)**: ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ### 404: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/meta-whatsapp/connections/{id}/disconnect" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Start Facebook Login for Messenger and Instagram `POST https://api.guidelab.co/integrations/meta-messaging/authorize` Documentation: https://docs.guidelab.co/api-reference/integrations/authorizeMetaMessaging ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Facebook consent URL - `url` (string) **(required)**: [uri] ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ### 429: Request could not be completed - `error` (string) **(required)**: ### 503: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/meta-messaging/authorize" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Complete Facebook Login and offer the granted Pages `GET https://api.guidelab.co/integrations/meta-messaging/callback` Documentation: https://docs.guidelab.co/api-reference/integrations/handleMetaMessagingCallback ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `code` (string) (in: query): - `state` (string) (in: query): - `error` (string) (in: query): ## Responses ### 302: Return to integration settings ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/meta-messaging/callback" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List the Pages granted by a pending Facebook Login `GET https://api.guidelab.co/integrations/meta-messaging/pages` Documentation: https://docs.guidelab.co/api-reference/integrations/listPendingMetaPages ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Granted Pages - `pages` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `instagramUsername` (string,null) **(required)**: ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ### 404: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/meta-messaging/pages" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Connect the chosen Page (and its Instagram account) `POST https://api.guidelab.co/integrations/meta-messaging/select` Documentation: https://docs.guidelab.co/api-reference/integrations/selectMetaPage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `pageId` (string) **(required)**: - `instagram` (boolean) **(required)**: ## Responses ### 200: The connections created - `connections` (object[]) **(required)**: - `id` (string) **(required)**: - `provider` (string) **(required)**: Values: `meta_whatsapp`, `twilio`, `telegram`, `meta_messaging`, `gmail`, `microsoft365` - `channel` (string) **(required)**: Values: `whatsapp`, `sms`, `telegram`, `messenger`, `instagram`, `email` - `address` (string,null) **(required)**: - `status` (string) **(required)**: Values: `pending`, `active`, `error`, `disconnected` - `statusMessage` (string,null) **(required)**: - `lastInboundAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: ### 400: Request could not be completed - `error` (string) **(required)**: ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ### 404: Request could not be completed - `error` (string) **(required)**: ### 409: Request could not be completed - `error` (string) **(required)**: ### 429: Request could not be completed - `error` (string) **(required)**: ### 502: Request could not be completed - `error` (string) **(required)**: ### 503: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/meta-messaging/select" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "pageId": "string", "instagram": true }' ``` --- # Disconnect Messenger and Instagram from the inbox `POST https://api.guidelab.co/integrations/meta-messaging/disconnect` Documentation: https://docs.guidelab.co/api-reference/integrations/disconnectMetaMessaging ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Disconnected - `ok` (boolean) **(required)**: ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/meta-messaging/disconnect" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Connect a Telegram bot to the inbox `POST https://api.guidelab.co/integrations/telegram` Documentation: https://docs.guidelab.co/api-reference/integrations/connectTelegramBot ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `botToken` (string) **(required)**: ## Responses ### 200: The connection - `connection` (object) **(required)**: - `id` (string) **(required)**: - `provider` (string) **(required)**: Values: `meta_whatsapp`, `twilio`, `telegram`, `meta_messaging`, `gmail`, `microsoft365` - `channel` (string) **(required)**: Values: `whatsapp`, `sms`, `telegram`, `messenger`, `instagram`, `email` - `address` (string,null) **(required)**: - `status` (string) **(required)**: Values: `pending`, `active`, `error`, `disconnected` - `statusMessage` (string,null) **(required)**: - `lastInboundAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: ### 400: Request could not be completed - `error` (string) **(required)**: ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ### 409: Request could not be completed - `error` (string) **(required)**: ### 429: Request could not be completed - `error` (string) **(required)**: ### 502: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/telegram" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "botToken": "string" }' ``` --- # Disconnect the Telegram bot from the inbox `POST https://api.guidelab.co/integrations/telegram/disconnect` Documentation: https://docs.guidelab.co/api-reference/integrations/disconnectTelegramBot ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Disconnected - `ok` (boolean) **(required)**: ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/telegram/disconnect" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Start Google consent for the Gmail inbox channel `POST https://api.guidelab.co/integrations/gmail/authorize` Documentation: https://docs.guidelab.co/api-reference/integrations/authorizeGmailInbox ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Google consent URL - `url` (string) **(required)**: [uri] ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ### 429: Request could not be completed - `error` (string) **(required)**: ### 503: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/gmail/authorize" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Complete Google consent and start watching the inbox `GET https://api.guidelab.co/integrations/gmail/callback` Documentation: https://docs.guidelab.co/api-reference/integrations/handleGmailInboxCallback ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `code` (string) (in: query): - `state` (string) (in: query): - `error` (string) (in: query): ## Responses ### 302: Return to integration settings ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/integrations/gmail/callback" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Disconnect the Gmail inbox channel `POST https://api.guidelab.co/integrations/gmail/disconnect` Documentation: https://docs.guidelab.co/api-reference/integrations/disconnectGmailInbox ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Disconnected - `ok` (boolean) **(required)**: ### 401: Request could not be completed - `error` (string) **(required)**: ### 403: Request could not be completed - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/integrations/gmail/disconnect" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Invoices `GET https://api.guidelab.co/invoices` Retrieve a paginated list of invoices for the authenticated lab. Supports filtering by status, clinic, and search text. Documentation: https://docs.guidelab.co/api-reference/invoices/listInvoices ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `status` (string) (in: query): - `search` (string) (in: query): - `sortBy` (string) (in: query): Values: `createdAt`, `issueDate`, `dueDate`, `invoiceNumber`, `totalAmount` Default: `createdAt` - `sortOrder` (string) (in: query): Values: `asc`, `desc` Default: `desc` - `clinicId` (string) (in: query): - `partnershipId` (string) (in: query): - `currency` (string) (in: query): Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `allTime` () (in: query): ## Responses ### 200: Paginated list of invoices with clinic details - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `invoiceNumber` (string) **(required)**: - `clinicId` (string) **(required)**: - `clinicName` (string,null) **(required)**: - `status` (string) **(required)**: - `subtotal` (string) **(required)**: - `taxAmount` (string,null) **(required)**: - `totalAmount` (string) **(required)**: - `amountPaid` (string) **(required)**: - `amountDue` (string) **(required)**: - `issueDate` (string) **(required)**: - `dueDate` (string) **(required)**: - `createdAt` (string) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid or malformed query parameters ## Example ```bash curl -X GET "https://api.guidelab.co/invoices" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Invoice `POST https://api.guidelab.co/invoices` Create a new invoice for a clinic. Lab-only. Automatically generates an invoice number; issued invoices create the corresponding account transaction while drafts remain ledger-neutral. Documentation: https://docs.guidelab.co/api-reference/invoices/createInvoice ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `idempotency-key` (string) **(required)** (in: header): Stable key reused only when retrying the exact same command body ## Request Body Content-Type: `application/json` - `clinicId` (string) **(required)**: - `orderId` (string): - `doctorUserId` (string): - `status` (string): (default: `draft`) Values: `draft`, `sent` - `discountAmount` (string): - `currency` (string): (default: `GBP`) Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `issueDate` (string) **(required)**: - `dueDate` (string): - `notes` (string): - `terms` (string): - `items` (object[]) **(required)**: - `orderId` (string): - `orderItemId` (string): - `description` (string) **(required)**: - `quantity` (integer): (default: `1`) - `unitPrice` (string) **(required)**: - `taxRate` (string,null): ## Responses ### 201: Invoice created successfully with line items - `id` (string) **(required)**: - `invoiceNumber` (string) **(required)**: - `items` (array) **(required)**: ### 400: Request body failed validation ### 404: Specified clinic not found ### 409: Issuance requires more than the supported number of prepayments ### 422: Idempotency-Key was already used with a different invoice body ## Example ```bash curl -X POST "https://api.guidelab.co/invoices" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "clinicId": "string", "issueDate": "string", "items": [ { "orderId": "string", "orderItemId": "string", "description": "string", "quantity": 0, "unitPrice": "string", "taxRate": "string" } ] }' ``` --- # Generate Invoices From Orders `POST https://api.guidelab.co/invoices/generate-from-orders` Batch-generate invoices from completed orders, grouped by clinic. Lab-only. Uses lab finance settings for default tax rate and due date calculation. Documentation: https://docs.guidelab.co/api-reference/invoices/generateInvoicesFromOrders ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `orderIds` (string[]) **(required)**: - `issueDate` (string): - `dueDate` (string): - `notes` (string): ## Responses ### 201: Invoices generated successfully with invoice IDs and count - `success` (boolean) **(required)**: - `invoiceIds` (string[]) **(required)**: - `count` (number) **(required)**: ### 400: Request body failed validation ### 404: None of the specified orders were found for this lab ## Example ```bash curl -X POST "https://api.guidelab.co/invoices/generate-from-orders" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "orderIds": [ "string" ], "issueDate": "string", "dueDate": "string", "notes": "string" }' ``` --- # Get Invoice By Order `GET https://api.guidelab.co/invoices/by-order/{orderId}` Look up the invoice associated with a specific order. Returns the full invoice detail including items and payments. Documentation: https://docs.guidelab.co/api-reference/invoices/getInvoiceByOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `orderId` (string) **(required)** (in: path): The order ID to look up the invoice for ## Responses ### 200: Full invoice detail for the specified order - `id` (string) **(required)**: - `invoiceNumber` (string) **(required)**: ### 404: No invoice found for the specified order ## Example ```bash curl -X GET "https://api.guidelab.co/invoices/by-order/{orderId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Invoice `GET https://api.guidelab.co/invoices/{id}` Retrieve full invoice details including line items, payments, clinic info, and Xero sync status. Documentation: https://docs.guidelab.co/api-reference/invoices/getInvoice ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Invoice ID ## Responses ### 200: Full invoice detail with items, payments, and related entities - `id` (string) **(required)**: - `invoiceNumber` (string) **(required)**: ### 404: Invoice not found or does not belong to this lab ## Example ```bash curl -X GET "https://api.guidelab.co/invoices/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Invoice `DELETE https://api.guidelab.co/invoices/{id}` Delete a draft invoice. Only invoices in draft status can be deleted; use status update to cancel non-draft invoices instead. Documentation: https://docs.guidelab.co/api-reference/invoices/deleteInvoice ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Invoice ID ## Responses ### 200: Invoice deleted successfully - `success` (boolean) **(required)**: ### 400: Invoice is not in draft status and cannot be deleted ### 404: Invoice not found or does not belong to this lab ## Example ```bash curl -X DELETE "https://api.guidelab.co/invoices/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Invoice `PUT https://api.guidelab.co/invoices/{id}` Edit draft invoice metadata or perform an allowed lifecycle transition. Financial headers are derived from line items and payment states are ledger-derived. Documentation: https://docs.guidelab.co/api-reference/invoices/updateInvoice ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Invoice ID ## Request Body Content-Type: `application/json` - `status` (string): Values: `draft`, `sent`, `paid`, `partially_paid`, `overdue`, `cancelled` - `doctorUserId` (string,null): - `discountAmount` (string,null): - `dueDate` (string): - `notes` (string,null): - `terms` (string,null): ## Responses ### 200: Updated invoice detail - `id` (string) **(required)**: - `invoiceNumber` (string) **(required)**: ### 400: Request body failed validation ### 404: Invoice not found or does not belong to this lab ### 409: Invoice has an online payment in progress or issuance requires too many prepayments ## Example ```bash curl -X PUT "https://api.guidelab.co/invoices/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "status": "draft", "doctorUserId": "string", "discountAmount": "string", "dueDate": "string", "notes": "string", "terms": "string" }' ``` --- # Record Invoice Payment `POST https://api.guidelab.co/invoices/{id}/payment` Record a manual payment against an invoice. Lab-only. Automatically updates invoice status (partially_paid/paid), creates a transaction record, and triggers Xero payment sync if configured. Documentation: https://docs.guidelab.co/api-reference/invoices/recordInvoicePayment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Invoice ID - `idempotency-key` (string) **(required)** (in: header): ## Request Body Content-Type: `application/json` - `amount` (string) **(required)**: - `acknowledgedOverpaymentAmount` (string): - `method` (string) **(required)**: Values: `card`, `bank_transfer`, `cash`, `cheque`, `direct_debit`, `other` - `reference` (string): - `paidAt` (string): - `notes` (string): - `reportingFxRate` (string): - `reportingFxEffectiveDate` (string): ## Responses ### 201: Payment recorded with updated invoice status and remaining balance - `success` (boolean) **(required)**: Values: `true` - `paymentId` (string) **(required)**: - `invoiceStatus` (string) **(required)**: - `amountPaid` (string) **(required)**: - `amountDue` (string) **(required)**: - `overpaymentAmount` (string) **(required)**: ### 400: Payment data failed validation ### 404: Invoice not found or does not belong to this lab ### 409: Idempotent request is still being processed or the invoice has an online payment in progress ### 422: Idempotency-Key was reused with different payment parameters ## Example ```bash curl -X POST "https://api.guidelab.co/invoices/{id}/payment" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "amount": "string", "method": "card" }' ``` --- # Email Invoice `POST https://api.guidelab.co/invoices/{id}/email` Send an invoice via email to the clinic's billing or primary email address. Lab-only. Also emits an in-app notification to clinic owners. Documentation: https://docs.guidelab.co/api-reference/invoices/emailInvoice ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Invoice ID - `idempotency-key` (string) **(required)** (in: header): Stable key reused only when retrying the exact same command body ## Responses ### 200: Invoice email sent successfully - `success` (boolean) **(required)**: ### 400: Clinic has no email address configured ### 404: Invoice not found or does not belong to this lab ### 429: Invoice email send budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/invoices/{id}/email" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Archive Invoice `POST https://api.guidelab.co/invoices/{id}/archive` Toggle the archive status of an invoice. If currently archived, it will be unarchived and vice versa. Archived invoices are excluded from default listing views. Documentation: https://docs.guidelab.co/api-reference/invoices/archiveInvoice ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Invoice ID ## Responses ### 200: Archive status toggled, returns new archived state - `success` (boolean) **(required)**: - `archived` (boolean) **(required)**: ### 404: Invoice not found or does not belong to this lab ## Example ```bash curl -X POST "https://api.guidelab.co/invoices/{id}/archive" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Credit Notes `GET https://api.guidelab.co/credit-notes` Retrieve a paginated list of credit notes for the authenticated lab. Supports filtering by status and search text. Documentation: https://docs.guidelab.co/api-reference/credit-notes/listCreditNotes ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `status` (string) (in: query): - `search` (string) (in: query): - `sortBy` (string) (in: query): Values: `createdAt`, `issueDate`, `creditNoteNumber`, `totalAmount` Default: `createdAt` - `sortOrder` (string) (in: query): Values: `asc`, `desc` Default: `desc` ## Responses ### 200: Paginated list of credit notes with clinic and allocation details - `data` (array) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid or malformed query parameters - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/credit-notes" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Credit Note `POST https://api.guidelab.co/credit-notes` Create an invoice-backed or manual account credit note. Invoice-backed clinic, partnership, currency, doctor identity, tax rate, and pricing mode are derived from the source invoice; manual doctor display data is resolved from a verified clinic member. Documentation: https://docs.guidelab.co/api-reference/credit-notes/createCreditNote ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `idempotency-key` (string) **(required)** (in: header): Stable key reused only when retrying the exact same command body ## Request Body Content-Type: `application/json` ## Responses ### 201: Credit note created successfully with ID and number - `id` (string) **(required)**: - `creditNoteNumber` (string) **(required)**: ### 400: Request body failed validation - `error` (string) **(required)**: ### 422: Idempotency-Key was already used with a different credit-note body ## Example ```bash curl -X POST "https://api.guidelab.co/credit-notes" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '"string"' ``` --- # Get Credit Note `GET https://api.guidelab.co/credit-notes/{id}` Retrieve full credit note details including line items, allocations, and remaining balance. Documentation: https://docs.guidelab.co/api-reference/credit-notes/getCreditNote ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Credit note ID ## Responses ### 200: Full credit note detail with items and allocations - `id` (string) **(required)**: - `creditNoteNumber` (string) **(required)**: ### 404: Credit note not found or does not belong to this lab - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/credit-notes/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Void Credit Note `DELETE https://api.guidelab.co/credit-notes/{id}` Void a credit note. Lab-only. Cannot void a credit note that has existing allocations; deallocate first. Documentation: https://docs.guidelab.co/api-reference/credit-notes/voidCreditNote ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Credit note ID ## Responses ### 200: Credit note voided successfully - `success` (boolean) **(required)**: ### 400: Credit note has existing allocations and cannot be voided - `error` (string) **(required)**: ### 404: Credit note not found or does not belong to this lab - `error` (string) **(required)**: ## Example ```bash curl -X DELETE "https://api.guidelab.co/credit-notes/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Email Credit Note `POST https://api.guidelab.co/credit-notes/{id}/email` Send a credit note via email to the clinic's billing or primary email address. Lab-only. Honours the lab's sales-credit email template setting. Documentation: https://docs.guidelab.co/api-reference/credit-notes/emailCreditNote ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Credit note ID ## Responses ### 200: Credit note email sent successfully - `success` (boolean) **(required)**: ### 400: Clinic has no email address or the sales-credit template is disabled - `error` (string) **(required)**: ### 404: Credit note not found or does not belong to this lab - `error` (string) **(required)**: ### 429: Credit note email send budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/credit-notes/{id}/email" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Allocate Credit Note `POST https://api.guidelab.co/credit-notes/{id}/allocate` Allocate credit from a credit note to an invoice. Lab-only. Reduces the invoice's amount due and the credit note's remaining balance. May mark the invoice as paid if fully covered. Documentation: https://docs.guidelab.co/api-reference/credit-notes/allocateCreditNote ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Credit note ID ## Request Body Content-Type: `application/json` - `idempotencyKey` (string) **(required)**: - `invoiceId` (string) **(required)**: - `amount` (string) **(required)**: ## Responses ### 200: Credit allocated with updated remaining credit and invoice amount due - `success` (boolean) **(required)**: - `newRemaining` (string) **(required)**: - `newAmountDue` (string) **(required)**: ### 400: Amount exceeds remaining credit, credit note is voided, or validation failed - `error` (string) **(required)**: ### 404: Credit note or target invoice not found - `error` (string) **(required)**: ### 409: Credit or invoice balance changed, or the invoice has an online payment in progress - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/credit-notes/{id}/allocate" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "idempotencyKey": "string", "invoiceId": "string", "amount": "string" }' ``` --- # Deallocate Credit Note `DELETE https://api.guidelab.co/credit-notes/{id}/allocations/{allocationId}` Reverse a credit-note allocation. Lab-only. Restores the credit note's remaining balance and the invoice's amount due (may revert the invoice from paid). Documentation: https://docs.guidelab.co/api-reference/credit-notes/deallocateCreditNote ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Credit note ID - `allocationId` (string) **(required)** (in: path): Allocation ID to reverse ## Responses ### 200: Allocation reversed with updated balances - `success` (boolean) **(required)**: - `invoiceStatus` (string) **(required)**: - `newRemaining` (string) **(required)**: - `newAmountDue` (string) **(required)**: ### 400: Allocation already reversed - `error` (string) **(required)**: ### 404: Allocation, credit note, or invoice not found - `error` (string) **(required)**: ### 409: Balance changed concurrently; retry - `error` (string) **(required)**: ## Example ```bash curl -X DELETE "https://api.guidelab.co/credit-notes/{id}/allocations/{allocationId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Refund Credit Note `POST https://api.guidelab.co/credit-notes/{id}/refund` Process a cash refund for remaining credit on a credit note. Lab-only. Creates a refund record and corresponding transaction. Documentation: https://docs.guidelab.co/api-reference/credit-notes/refundCreditNote ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Credit note ID ## Request Body Content-Type: `application/json` - `idempotencyKey` (string) **(required)**: - `amount` (string) **(required)**: - `method` (string): (default: `bank_transfer`) Values: `bank_transfer`, `cash`, `cheque`, `card` - `reference` (string): - `notes` (string): - `reportingFxRate` (string): - `reportingFxEffectiveDate` (string): ## Responses ### 201: Refund processed successfully with refund ID - `success` (boolean) **(required)**: - `refundId` (string) **(required)**: ### 400: Amount exceeds remaining credit or validation failed - `error` (string) **(required)**: ### 404: Credit note not found or does not belong to this lab - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/credit-notes/{id}/refund" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "idempotencyKey": "string", "amount": "string" }' ``` --- # List Statements `GET https://api.guidelab.co/statements` Retrieve a paginated list of statements for the authenticated lab. Lab-only. Supports filtering by status and search text. Documentation: https://docs.guidelab.co/api-reference/statements/listStatements ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `status` (string) (in: query): - `search` (string) (in: query): - `sortBy` (string) (in: query): Values: `createdAt`, `periodStart`, `statementNumber`, `totalDue` Default: `createdAt` - `sortOrder` (string) (in: query): Values: `asc`, `desc` Default: `desc` ## Responses ### 200: Paginated list of statements with clinic details - `data` (array) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid or malformed query parameters - `error` (string) **(required)**: ### 409: Statement email delivery is already in progress - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/statements" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Generate Statement `POST https://api.guidelab.co/statements` Generate a new statement for a clinic with outstanding or activity data. Lab-only. Automatically calculates aged balances, line items, and running totals. Documentation: https://docs.guidelab.co/api-reference/statements/generateStatement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `partnershipId` (string) **(required)**: - `type` (string): (default: `outstanding`) Values: `outstanding`, `activity` - `asOfDate` (string): - `periodStart` (string): - `periodEnd` (string): - `currency` (string) **(required)**: Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `notes` (string): ## Responses ### 201: Statement generated successfully with statement ID and number - `success` (boolean) **(required)**: - `statementId` (string) **(required)**: - `statementNumber` (string) **(required)**: ### 400: Request body failed validation - `error` (string) **(required)**: ### 413: Statement line-item limit exceeded - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/statements" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "partnershipId": "string", "currency": "GBP" }' ``` --- # Get Statement `GET https://api.guidelab.co/statements/{id}` Retrieve full statement details including line items, aged balances, and totals. Lab-only. Documentation: https://docs.guidelab.co/api-reference/statements/getStatement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Statement ID ## Responses ### 200: Full statement detail with line items and balance breakdown - `id` (string) **(required)**: - `statementNumber` (string) **(required)**: ### 404: Statement not found or does not belong to this lab - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/statements/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Email Statement `POST https://api.guidelab.co/statements/{id}/email` Send a statement via email to the clinic's billing or primary email address. Lab-only. Updates the statement status to sent. Documentation: https://docs.guidelab.co/api-reference/statements/emailStatement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Statement ID ## Responses ### 200: Statement email sent and status updated to sent - `success` (boolean) **(required)**: ### 400: Clinic has no email address configured - `error` (string) **(required)**: ### 404: Statement or clinic not found - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/statements/{id}/email" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Consolidations `GET https://api.guidelab.co/consolidations` Retrieve a paginated list of invoice consolidations for the authenticated lab. Lab-only. Supports filtering by status and search text. Documentation: https://docs.guidelab.co/api-reference/consolidations/listConsolidations ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `status` (string) (in: query): - `search` (string) (in: query): - `sortBy` (string) (in: query): Values: `createdAt`, `consolidationNumber`, `totalAmount`, `dueDate` Default: `createdAt` - `sortOrder` (string) (in: query): Values: `asc`, `desc` Default: `desc` ## Responses ### 200: Paginated list of consolidations with invoice counts and totals - `data` (array) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid or malformed query parameters - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/consolidations" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Consolidation `POST https://api.guidelab.co/consolidations` Create a new invoice consolidation by grouping multiple invoices. Lab-only. Links selected invoices to the consolidation and calculates aggregate totals. Documentation: https://docs.guidelab.co/api-reference/consolidations/createConsolidation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` ## Responses ### 201: Consolidation created with ID and consolidation number - `success` (boolean) **(required)**: - `consolidationId` (string) **(required)**: - `consolidationNumber` (string) **(required)**: ### 400: One or more invoices not found or validation failed - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/consolidations" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '"string"' ``` --- # Get Consolidation `GET https://api.guidelab.co/consolidations/{id}` Retrieve full consolidation details including linked invoices and totals. Lab-only. Documentation: https://docs.guidelab.co/api-reference/consolidations/getConsolidation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Consolidation ID ## Responses ### 200: Full consolidation detail with linked invoices - `id` (string) **(required)**: - `consolidationNumber` (string) **(required)**: ### 404: Consolidation not found or does not belong to this lab - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/consolidations/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Consolidation `DELETE https://api.guidelab.co/consolidations/{id}` Delete a draft consolidation and unlink its invoices. Lab-only. Only consolidations in draft status can be deleted. Documentation: https://docs.guidelab.co/api-reference/consolidations/deleteConsolidation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Consolidation ID ## Responses ### 200: Consolidation deleted and invoices unlinked - `success` (boolean) **(required)**: ### 400: Consolidation is not in draft status and cannot be deleted - `error` (string) **(required)**: ### 404: Consolidation not found or does not belong to this lab - `error` (string) **(required)**: ## Example ```bash curl -X DELETE "https://api.guidelab.co/consolidations/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Email Consolidation `POST https://api.guidelab.co/consolidations/{id}/email` Send a consolidated invoice via email to the billing-owner clinic. Lab-only. Honours the lab's consolidated-invoice email template setting. Documentation: https://docs.guidelab.co/api-reference/consolidations/emailConsolidation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Consolidation ID ## Responses ### 200: Consolidated invoice email sent successfully - `success` (boolean) **(required)**: ### 400: No billing-owner email or the consolidated-invoice template is disabled - `error` (string) **(required)**: ### 404: Consolidation not found or does not belong to this lab - `error` (string) **(required)**: ### 409: Consolidation authority or invoice eligibility changed - `error` (string) **(required)**: ### 429: Consolidation email send budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/consolidations/{id}/email" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Transactions `GET https://api.guidelab.co/transactions` Retrieve a paginated list of financial transactions (invoices, payments, credit notes, refunds) for the authenticated lab. Supports filtering by type, clinic, and date range. Documentation: https://docs.guidelab.co/api-reference/transactions/listTransactions ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `type` (string) (in: query): - `search` (string) (in: query): - `clinicId` (string) (in: query): - `partnershipId` (string) (in: query): - `currency` (string) (in: query): Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `dateFrom` (string) (in: query): - `dateTo` (string) (in: query): - `sortBy` (string) (in: query): Values: `transactionDate`, `createdAt`, `amount` Default: `transactionDate` - `sortOrder` (string) (in: query): Values: `asc`, `desc` Default: `desc` ## Responses ### 200: Paginated list of transactions with related entity details - `data` (array) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid or malformed query parameters - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/transactions" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Overpayments `GET https://api.guidelab.co/overpayments` Retrieve a paginated list of payments with overpayment amounts for the authenticated lab. Includes refund totals and remaining overpayment balances. Documentation: https://docs.guidelab.co/api-reference/overpayments/listOverpayments ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` ## Responses ### 200: Paginated list of overpayments with clinic names, refund totals, and remaining balances - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `invoiceId` (string,null) **(required)**: - `labId` (string) **(required)**: - `clinicId` (string) **(required)**: - `amount` (string) **(required)**: - `overpaymentAmount` (string) **(required)**: - `currency` (string) **(required)**: - `method` (string) **(required)**: - `status` (string) **(required)**: - `reference` (string,null) **(required)**: - `paidAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `clinicName` (string,null) **(required)**: - `invoiceNumber` (string,null) **(required)**: - `refundedAmount` (string) **(required)**: - `remainingOverpayment` (string) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/overpayments" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Refund Overpayment `POST https://api.guidelab.co/overpayments/{id}/refund` Process a refund for an overpayment on a completed payment. Lab-only. Creates a refund record and corresponding account-debit transaction. Documentation: https://docs.guidelab.co/api-reference/overpayments/refundOverpayment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Payment ID with the overpayment ## Request Body Content-Type: `application/json` - `idempotencyKey` (string) **(required)**: - `amount` (string) **(required)**: - `method` (string): (default: `bank_transfer`) Values: `bank_transfer`, `cash`, `cheque`, `card`, `stripe` - `reference` (string): - `notes` (string): ## Responses ### 201: Overpayment refund processed successfully with refund ID - `success` (boolean) **(required)**: - `refundId` (string) **(required)**: - `status` (string) **(required)**: Values: `pending`, `completed` ### 202: Stripe refund is pending provider confirmation - `success` (boolean) **(required)**: - `refundId` (string) **(required)**: - `status` (string) **(required)**: Values: `pending` ### 400: Amount exceeds remaining overpayment or validation failed - `error` (string) **(required)**: ### 404: Payment not found or has no overpayment balance - `error` (string) **(required)**: ### 409: Idempotency key or refund method conflicts ### 502: Stripe could not confirm the refund ### 503: Stripe is not configured safely ## Example ```bash curl -X POST "https://api.guidelab.co/overpayments/{id}/refund" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "idempotencyKey": "string", "amount": "string", "method": "bank_transfer", "reference": "string", "notes": "string" }' ``` --- # Get Finance Settings `GET https://api.guidelab.co/finance-settings` Retrieve the lab's finance settings including tax rates, payment terms, invoice automation, late fee configuration, and Stripe Connect status. Lab-only. Documentation: https://docs.guidelab.co/api-reference/finance-settings/getFinanceSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Lab finance settings object, returns defaults if not yet configured - `settings` (object): - `canCollectStripePayments` (boolean) **(required)**: ### 403: Only lab organizations can access finance settings - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/finance-settings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Finance Settings `PUT https://api.guidelab.co/finance-settings` Update the lab's finance settings. Lab-only. Creates the settings record if it does not yet exist (upsert behavior). Documentation: https://docs.guidelab.co/api-reference/finance-settings/updateFinanceSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `invoiceDuePolicy` (string): Values: `net_days`, `day_of_month` - `invoiceTermDays` (integer,null): - `invoiceDueDay` (integer,null): - `invoiceDueMonthRule` (string,null): Values: `next_occurrence`, `following_month`, `null` - `invoiceReminderOnIssue` (boolean): - `invoiceReminderOffsetsDays` (array): - `creditHoldEnabledByDefault` (boolean): - `paymentTerms` (string,null): - `bankingDetails` (string,null): - `nominalCode` (string,null): - `invoiceRetentionMonths` (integer): - `showPatientInStatements` (boolean): - `statementAddressLower` (boolean): - `statementDay` (integer): - `termsAndConditions` (string,null): - `lateFeeEnabled` (boolean): - `lateFeeType` (string): Values: `flat`, `percentage` - `lateFeeAmount` (string): - `lateFeeCurrency` (string,null): Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR`, `null` - `lateFeeFrequency` (string): Values: `once`, `monthly` - `lateFeeGracePeriod` (integer): - `lateFeeLabel` (string,null): - `salesInvoiceTemplateEnabled` (boolean): - `salesInvoiceAutomate` (boolean): - `salesCreditTemplateEnabled` (boolean): - `salesCreditAutomate` (boolean): - `statementTemplateEnabled` (boolean): - `statementAutomate` (boolean): - `consolidatedInvoiceTemplateEnabled` (boolean): - `consolidatedInvoiceAutomate` (boolean): - `taxMode` (string): Values: `none`, `exclusive`, `inclusive` - `defaultTaxRate` (string,null): - `chargeStampDuty` (boolean): - `defaultPaymentPolicy` (string): Values: `pay_on_invoice`, `pay_in_advance`, `pay_now_or_later` - `upfrontPaymentDiscountPercent` (string): ## Responses ### 200: Updated finance settings object - `settings` (object): ### 400: Request body failed validation - `error` (string) **(required)**: ### 403: Only lab organizations can manage finance settings - `error` (string) **(required)**: ### 409: An upfront payment policy needs the lab's sales tax policy configured first - `error` (string) **(required)**: - `code` (string) **(required)**: Values: `tax_policy_unconfigured` ## Example ```bash curl -X PUT "https://api.guidelab.co/finance-settings" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # List Stripe Connect Quarantine `GET https://api.guidelab.co/finances/stripe-quarantine` List 25 held Connect events for the active lab, with at most three normalized review outcomes per event. Documentation: https://docs.guidelab.co/api-reference/finances/listStripeConnectQuarantine ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `before` (string) (in: query): - `beforeId` (string) (in: query): ## Responses ### 200: Held event evidence and keyset cursor - `data` (object[]) **(required)**: - `eventId` (string) **(required)**: - `stripeAccountId` (string) **(required)**: - `stripePaymentIntentId` (string,null) **(required)**: - `type` (string) **(required)**: - `quarantineReason` (string) **(required)**: - `receivedAt` (string) **(required)**: - `reviews` (object[]) **(required)**: - `id` (string) **(required)**: - `attempt` (integer) **(required)**: - `reviewerUserId` (string) **(required)**: - `outcome` (string) **(required)**: Values: `pending`, `applied`, `still_quarantined`, `provider_unavailable`, `provenance_mismatch`, `interrupted` - `errorCode` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `finishedAt` (string,null) **(required)**: - `canReplay` (boolean) **(required)**: - `next` (object,null) **(required)**: - `before` (string) **(required)**: - `beforeId` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/finances/stripe-quarantine" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Stripe Connect Quarantine `GET https://api.guidelab.co/finances/stripe-quarantine/{eventId}` Inspect an exact held event and its retained review history without contacting Stripe. Documentation: https://docs.guidelab.co/api-reference/finances/getStripeConnectQuarantine ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `eventId` (string) **(required)** (in: path): ## Responses ### 200: Normalized evidence - `eventId` (string) **(required)**: - `stripeAccountId` (string) **(required)**: - `stripePaymentIntentId` (string,null) **(required)**: - `type` (string) **(required)**: - `quarantineReason` (string) **(required)**: - `receivedAt` (string) **(required)**: - `reviews` (object[]) **(required)**: - `id` (string) **(required)**: - `attempt` (integer) **(required)**: - `reviewerUserId` (string) **(required)**: - `outcome` (string) **(required)**: Values: `pending`, `applied`, `still_quarantined`, `provider_unavailable`, `provenance_mismatch`, `interrupted` - `errorCode` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `finishedAt` (string,null) **(required)**: - `canReplay` (boolean) **(required)**: ### 404: Event not found in this lab ## Example ```bash curl -X GET "https://api.guidelab.co/finances/stripe-quarantine/{eventId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Replay Stripe Connect Quarantine `POST https://api.guidelab.co/finances/stripe-quarantine/{eventId}/replay` Replay exact provider evidence against a retained claim. One Stripe read, at most three lifetime attempts, immutable ingress receipt and durable review outcome. Does not charge, refund, discover or relabel payments. Documentation: https://docs.guidelab.co/api-reference/finances/replayStripeConnectQuarantine ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `eventId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `idempotencyKey` (string) **(required)**: ## Responses ### 200: Review outcome, including unresolved evidence - `eventId` (string) **(required)**: - `stripeAccountId` (string) **(required)**: - `stripePaymentIntentId` (string,null) **(required)**: - `type` (string) **(required)**: - `quarantineReason` (string) **(required)**: - `receivedAt` (string) **(required)**: - `reviews` (object[]) **(required)**: - `id` (string) **(required)**: - `attempt` (integer) **(required)**: - `reviewerUserId` (string) **(required)**: - `outcome` (string) **(required)**: Values: `pending`, `applied`, `still_quarantined`, `provider_unavailable`, `provenance_mismatch`, `interrupted` - `errorCode` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `finishedAt` (string,null) **(required)**: - `canReplay` (boolean) **(required)**: ### 404: Event not found in this lab ### 409: Review in progress or lifetime attempts exhausted ### 429: Provider review budget exhausted ## Example ```bash curl -X POST "https://api.guidelab.co/finances/stripe-quarantine/{eventId}/replay" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "idempotencyKey": "string" }' ``` --- # Get Cashflow `GET https://api.guidelab.co/finances/cashflow` Return bounded monthly cash receipts, refunds, expenses, and net cash in the lab reporting currency. Documentation: https://docs.guidelab.co/api-reference/finances/getCashflow ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `period` (string) (in: query): Values: `7m`, `12m`, `ytd` Default: `7m` ## Responses ### 200: Monthly cashflow - `period` (string) **(required)**: Values: `7m`, `12m`, `ytd` - `currency` (string) **(required)**: - `from` (string) **(required)**: - `to` (string) **(required)**: - `points` (object[]) **(required)**: - `month` (string) **(required)**: - `receipts` (string) **(required)**: - `refunds` (string) **(required)**: - `expenses` (string) **(required)**: - `net` (string) **(required)**: - `totals` (object) **(required)**: - `receipts` (string) **(required)**: - `refunds` (string) **(required)**: - `expenses` (string) **(required)**: - `net` (string) **(required)**: ### 409: Organization timezone or currency is not usable for reporting - `error` (string) **(required)**: - `code` (string) **(required)**: Values: `ORGANIZATION_CONFIGURATION_INVALID` ## Example ```bash curl -X GET "https://api.guidelab.co/finances/cashflow" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Expense Categories `GET https://api.guidelab.co/finances/expense-categories` Documentation: https://docs.guidelab.co/api-reference/finances/listExpenseCategories ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` () (in: query): Default: `false` ## Responses ### 200: Expense categories - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `isActive` (boolean) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (object): - `updatedAt` (object): ## Example ```bash curl -X GET "https://api.guidelab.co/finances/expense-categories" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Expense Category `POST https://api.guidelab.co/finances/expense-categories` Documentation: https://docs.guidelab.co/api-reference/finances/createExpenseCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: ## Responses ### 201: Expense category created - `data` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `isActive` (boolean) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (object): - `updatedAt` (object): ### 409: Duplicate category or category ceiling reached ## Example ```bash curl -X POST "https://api.guidelab.co/finances/expense-categories" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string" }' ``` --- # Update Expense Category `PATCH https://api.guidelab.co/finances/expense-categories/{id}` Documentation: https://docs.guidelab.co/api-reference/finances/updateExpenseCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `name` (string): - `isActive` (boolean): ## Responses ### 200: Expense category updated - `data` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `isActive` (boolean) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (object): - `updatedAt` (object): ### 404: Expense category not found ### 409: Duplicate expense category name ## Example ```bash curl -X PATCH "https://api.guidelab.co/finances/expense-categories/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "isActive": true }' ``` --- # Delete Expense Category `DELETE https://api.guidelab.co/finances/expense-categories/{id}` Documentation: https://docs.guidelab.co/api-reference/finances/deleteExpenseCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Unused expense category deleted ### 404: Expense category not found ### 409: Expense category is in use ## Example ```bash curl -X DELETE "https://api.guidelab.co/finances/expense-categories/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Expenses `GET https://api.guidelab.co/finances/expenses` Documentation: https://docs.guidelab.co/api-reference/finances/listExpenses ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `25` - `status` (string) (in: query): Values: `pending`, `paid`, `void` - `categoryId` (string) (in: query): - `from` (string) (in: query): - `to` (string) (in: query): ## Responses ### 200: Paginated manual expenses - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string) **(required)**: - `description` (string) **(required)**: - `originalAmount` (string) **(required)**: - `originalCurrency` (string) **(required)**: - `reportingAmount` (string) **(required)**: - `reportingCurrency` (string) **(required)**: - `status` (string) **(required)**: - `occurredOn` (string) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Expense date range is too wide ## Example ```bash curl -X GET "https://api.guidelab.co/finances/expenses" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Expense `POST https://api.guidelab.co/finances/expenses` Documentation: https://docs.guidelab.co/api-reference/finances/createExpense ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `idempotency-key` (string) **(required)** (in: header): Stable key reused only when retrying the exact same command body ## Request Body Content-Type: `application/json` - `categoryId` (string) **(required)**: - `supplierId` (string,null): - `purchaseOrderId` (string,null): - `description` (string) **(required)**: - `originalAmount` (string) **(required)**: - `originalCurrency` (string) **(required)**: Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `occurredOn` (string) **(required)**: - `paidAt` (string,null): - `status` (string): (default: `paid`) Values: `pending`, `paid` - `reference` (string,null): - `notes` (string,null): - `reportingFxRate` (string): - `reportingFxEffectiveDate` (string): ## Responses ### 200: Exact idempotent replay ### 201: Expense created - `data` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string) **(required)**: - `description` (string) **(required)**: - `originalAmount` (string) **(required)**: - `originalCurrency` (string) **(required)**: - `reportingAmount` (string) **(required)**: - `reportingCurrency` (string) **(required)**: - `status` (string) **(required)**: - `occurredOn` (string) **(required)**: ### 400: Invalid reporting FX input ### 404: Category, supplier, or purchase order not found ### 409: Reference or idempotency conflict ### 422: Idempotency-Key reused for a different expense ## Example ```bash curl -X POST "https://api.guidelab.co/finances/expenses" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "categoryId": "string", "description": "string", "originalAmount": "string", "originalCurrency": "GBP", "occurredOn": "string" }' ``` --- # Update Expense `PATCH https://api.guidelab.co/finances/expenses/{id}` Documentation: https://docs.guidelab.co/api-reference/finances/updateExpense ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `categoryId` (string): - `supplierId` (string,null): - `purchaseOrderId` (string,null): - `description` (string): - `originalAmount` (string): - `originalCurrency` (string): Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `occurredOn` (string): - `paidAt` (string,null): - `status` (string): Values: `pending`, `paid` - `reference` (string,null): - `notes` (string,null): - `reportingFxRate` (string): - `reportingFxEffectiveDate` (string): ## Responses ### 200: Pending expense updated - `data` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string) **(required)**: - `description` (string) **(required)**: - `originalAmount` (string) **(required)**: - `originalCurrency` (string) **(required)**: - `reportingAmount` (string) **(required)**: - `reportingCurrency` (string) **(required)**: - `status` (string) **(required)**: - `occurredOn` (string) **(required)**: ### 400: Invalid lifecycle or reporting FX input ### 404: Expense not found ### 409: Paid or void expense cannot be edited ## Example ```bash curl -X PATCH "https://api.guidelab.co/finances/expenses/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Delete Expense `DELETE https://api.guidelab.co/finances/expenses/{id}` Documentation: https://docs.guidelab.co/api-reference/finances/deleteExpense ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Pending expense deleted ### 404: Expense not found ### 409: Paid or void expense cannot be deleted ## Example ```bash curl -X DELETE "https://api.guidelab.co/finances/expenses/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Void Expense `POST https://api.guidelab.co/finances/expenses/{id}/void` Documentation: https://docs.guidelab.co/api-reference/finances/voidExpense ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `reason` (string) **(required)**: ## Responses ### 200: Expense voided - `data` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string) **(required)**: - `description` (string) **(required)**: - `originalAmount` (string) **(required)**: - `originalCurrency` (string) **(required)**: - `reportingAmount` (string) **(required)**: - `reportingCurrency` (string) **(required)**: - `status` (string) **(required)**: - `occurredOn` (string) **(required)**: ### 404: Expense not found ### 409: Expense already void ## Example ```bash curl -X POST "https://api.guidelab.co/finances/expenses/{id}/void" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "reason": "string" }' ``` --- # Get Finances Overview `GET https://api.guidelab.co/finances/overview` Retrieve a finance dashboard overview for the authenticated lab. Lab-only. Returns key metrics (outstanding, invoiced this month, payments this month, overdue), plus recent invoices and payments. Documentation: https://docs.guidelab.co/api-reference/finances/getFinancesOverview ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Finance overview with key metrics, recent invoices, and recent payments - `metrics` (object) **(required)**: - `currencyTotals` (object[]) **(required)**: - `currency` (string) **(required)**: - `totalOutstanding` (string) **(required)**: - `invoicedThisMonth` (string) **(required)**: - `invoicedThisMonthCount` (number) **(required)**: - `paymentsThisMonth` (string) **(required)**: - `paymentsThisMonthCount` (number) **(required)**: - `overdueAmount` (string) **(required)**: - `overdueCount` (number) **(required)**: - `recentInvoices` (object[]) **(required)**: - `id` (string) **(required)**: - `invoiceNumber` (string) **(required)**: - `clinicName` (string) **(required)**: - `clinicNameMissing` (boolean) **(required)**: - `status` (string) **(required)**: - `totalAmount` (string) **(required)**: - `amountDue` (string) **(required)**: - `dueDate` (string,null) **(required)**: - `issueDate` (string) **(required)**: - `currency` (string) **(required)**: - `recentPayments` (object[]) **(required)**: - `id` (string) **(required)**: - `invoiceId` (string,null) **(required)**: - `invoiceNumber` (string,null) **(required)**: - `clinicName` (string) **(required)**: - `clinicNameMissing` (boolean) **(required)**: - `amount` (string) **(required)**: - `method` (string) **(required)**: - `status` (string) **(required)**: - `paidAt` (string) **(required)**: - `currency` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/finances/overview" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Finance Accounts `GET https://api.guidelab.co/finances/accounts` Retrieve a paginated list of clinic accounts with financial summaries. Lab-only. Shows total invoiced, paid, outstanding, overdue, and credit balance per partner clinic. Documentation: https://docs.guidelab.co/api-reference/finances/listFinanceAccounts ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `search` (string) (in: query): - `sortBy` (string) (in: query): Values: `clinicName`, `outstanding`, `totalInvoiced`, `lastPaymentDate` Default: `clinicName` - `sortOrder` (string) (in: query): Values: `asc`, `desc` Default: `asc` ## Responses ### 200: Paginated list of clinic accounts with financial aggregates - `data` (object[]) **(required)**: - `partnershipId` (string) **(required)**: - `partnershipStatus` (string) **(required)**: - `clinicId` (string) **(required)**: - `clinicName` (string) **(required)**: - `clinicNameMissing` (boolean) **(required)**: - `currency` (string) **(required)**: - `totalInvoiced` (string) **(required)**: - `totalPaid` (string) **(required)**: - `outstanding` (string) **(required)**: - `overdue` (string) **(required)**: - `creditBalance` (string) **(required)**: - `lastPaymentDate` (string,null) **(required)**: - `invoiceCount` (number) **(required)**: - `hasActivity` (boolean) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid or malformed query parameters - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/finances/accounts" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Finance Account `GET https://api.guidelab.co/finances/accounts/{id}` Retrieve financial summary for a specific clinic account. Lab-only. Returns total invoiced, paid, outstanding, overdue, credit balance, and last payment date. Documentation: https://docs.guidelab.co/api-reference/finances/getFinanceAccount ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Partnership (account epoch) ID - `currency` (string) **(required)** (in: query): Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` ## Responses ### 200: Clinic account financial summary - `partnershipId` (string) **(required)**: - `partnershipStatus` (string) **(required)**: - `clinicId` (string) **(required)**: - `clinicName` (string) **(required)**: - `clinicNameMissing` (boolean) **(required)**: - `currency` (string) **(required)**: - `totalInvoiced` (string) **(required)**: - `totalPaid` (string) **(required)**: - `outstanding` (string) **(required)**: - `overdue` (string) **(required)**: - `creditBalance` (string) **(required)**: - `lastPaymentDate` (string,null) **(required)**: - `invoiceCount` (number) **(required)**: - `hasActivity` (boolean) **(required)**: ### 404: The requested account epoch/currency was not found - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/finances/accounts/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Aged Balances `GET https://api.guidelab.co/finances/aged-balances` Retrieve aged balance report across all partner clinics. Lab-only. Breaks down outstanding amounts into current, 30-day, 60-day, and 90+ day buckets with per-clinic and grand totals. Documentation: https://docs.guidelab.co/api-reference/finances/getAgedBalances ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `search` (string) (in: query): Filter clinics by name - `asOfDate` (string) (in: query): Reference date for ageing calculations ## Responses ### 200: Aged balance rows per clinic with bucket totals and grand totals - `rows` (object[]) **(required)**: - `partnershipId` (string) **(required)**: - `partnershipStatus` (string) **(required)**: - `clinicId` (string) **(required)**: - `clinicName` (string) **(required)**: - `clinicNameMissing` (boolean) **(required)**: - `currency` (string) **(required)**: - `current` (string) **(required)**: - `days30` (string) **(required)**: - `days60` (string) **(required)**: - `days90Plus` (string) **(required)**: - `total` (string) **(required)**: - `totals` (object[]) **(required)**: - `currency` (string) **(required)**: - `current` (string) **(required)**: - `days30` (string) **(required)**: - `days60` (string) **(required)**: - `days90Plus` (string) **(required)**: - `total` (string) **(required)**: ### 400: Historical ageing is unavailable from mutable current invoice balances - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/finances/aged-balances" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Stripe External Adjustments `GET https://api.guidelab.co/finances/external-adjustments` List unresolved Stripe dashboard refunds, disputes, and refund gaps for the authenticated lab. Lab owner/admin only. Documentation: https://docs.guidelab.co/api-reference/finances/listStripeExternalAdjustments ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` ## Responses ### 200: Paginated unresolved external Stripe adjustments - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `paymentId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `clinicId` (string) **(required)**: - `clinicName` (string) **(required)**: - `kind` (string) **(required)**: Values: `refund`, `dispute`, `refund_gap` - `amount` (string) **(required)**: - `resolutionAmount` (string) **(required)**: - `currency` (string) **(required)**: - `providerStatus` (string) **(required)**: - `effectState` (string) **(required)**: Values: `none`, `debited`, `reinstated` - `reviewReason` (string) **(required)**: - `providerReference` (string,null) **(required)**: - `paymentReference` (string,null) **(required)**: - `lastProviderEventAt` (string) **(required)**: - `createdAt` (string) **(required)**: - `canResolve` (boolean) **(required)**: - `allowedResolutionTypes` (string[]) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/finances/external-adjustments" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Stripe External Adjustment `GET https://api.guidelab.co/finances/external-adjustments/{id}` View an unresolved external Stripe adjustment and source-receipt invoice candidates. Lab owner/admin only. Documentation: https://docs.guidelab.co/api-reference/finances/getStripeExternalAdjustment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: External Stripe adjustment review detail - `id` (string) **(required)**: - `paymentId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `clinicId` (string) **(required)**: - `clinicName` (string) **(required)**: - `kind` (string) **(required)**: Values: `refund`, `dispute`, `refund_gap` - `amount` (string) **(required)**: - `resolutionAmount` (string) **(required)**: - `currency` (string) **(required)**: - `providerStatus` (string) **(required)**: - `effectState` (string) **(required)**: Values: `none`, `debited`, `reinstated` - `reviewReason` (string) **(required)**: - `providerReference` (string,null) **(required)**: - `paymentReference` (string,null) **(required)**: - `lastProviderEventAt` (string) **(required)**: - `createdAt` (string) **(required)**: - `canResolve` (boolean) **(required)**: - `allowedResolutionTypes` (string[]) **(required)**: - `stripePaymentIntentId` (string) **(required)**: - `stripeChargeId` (string) **(required)**: - `invoiceCandidates` (object[]) **(required)**: - `invoiceId` (string) **(required)**: - `invoiceNumber` (string) **(required)**: - `status` (string) **(required)**: - `issueDate` (string) **(required)**: - `totalAmount` (string) **(required)**: - `amountPaid` (string) **(required)**: - `amountDue` (string) **(required)**: - `sourceAllocatedAmount` (string) **(required)**: - `currency` (string) **(required)**: ### 404: Unresolved adjustment not found - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/finances/external-adjustments/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Resolve Stripe External Adjustment `POST https://api.guidelab.co/finances/external-adjustments/{id}/resolve` Resolve one external Stripe adjustment by classifying its immutable debit against source-receipt invoices or retaining it explicitly at account level. Lab owner/admin only. Documentation: https://docs.guidelab.co/api-reference/finances/resolveStripeExternalAdjustment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` ## Responses ### 200: Adjustment review resolved - `success` (boolean) **(required)**: Values: `true` - `resolutionId` (string) **(required)**: - `resolutionType` (string) **(required)**: Values: `allocate`, `account_adjustment` - `resolvedAt` (string) **(required)**: ### 400: Invalid invoice allocation ### 404: Unresolved adjustment not found ### 409: Review state or idempotency conflict ## Example ```bash curl -X POST "https://api.guidelab.co/finances/external-adjustments/{id}/resolve" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '"string"' ``` --- # List Clinic Invoices `GET https://api.guidelab.co/clinic-finances/invoices` Retrieve a paginated list of invoices received by the authenticated clinic. Clinic-only. Supports filtering by status, search, and sorting. Documentation: https://docs.guidelab.co/api-reference/clinic-finances/listClinicInvoices ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `status` (string) (in: query): - `search` (string) (in: query): - `sortBy` (string) (in: query): Values: `createdAt`, `issueDate`, `dueDate`, `invoiceNumber`, `totalAmount` Default: `createdAt` - `sortOrder` (string) (in: query): Values: `asc`, `desc` Default: `desc` - `clinicId` (string) (in: query): - `partnershipId` (string) (in: query): - `currency` (string) (in: query): Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `allTime` () (in: query): ## Responses ### 200: Paginated list of invoices with lab details - `data` (array) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid or malformed query parameters - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/clinic-finances/invoices" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Clinic Invoices By Order `GET https://api.guidelab.co/clinic-finances/invoices/by-order/{orderId}` Look up invoices associated with a specific order for the authenticated clinic. Clinic-only. Returns a list since an order may have multiple invoices. Documentation: https://docs.guidelab.co/api-reference/clinic-finances/getClinicInvoicesByOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `orderId` (string) **(required)** (in: path): Order ID to look up invoices for ## Responses ### 200: List of invoices linked to the specified order Array of: - `id` (string) **(required)**: - `invoiceNumber` (string) **(required)**: - `status` (string) **(required)**: - `presentedStatus` (string) **(required)**: Status as the clinic should see it: `overdue` once a payable invoice is past its due date with a balance, otherwise the stored status. - `totalAmount` (string) **(required)**: - `amountPaid` (string) **(required)**: - `amountDue` (string) **(required)**: - `currency` (string) **(required)**: - `dueDate` (string) **(required)**: - `labId` (string) **(required)**: - `partnershipId` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/clinic-finances/invoices/by-order/{orderId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Clinic Invoice `GET https://api.guidelab.co/clinic-finances/invoices/{id}` Retrieve full invoice details including line items and payment history. Clinic-only. Only returns invoices belonging to the authenticated clinic. Documentation: https://docs.guidelab.co/api-reference/clinic-finances/getClinicInvoice ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Invoice ID ## Responses ### 200: Full invoice detail with items, payments, and lab info - `id` (string) **(required)**: - `invoiceNumber` (string) **(required)**: - `status` (string) **(required)**: - `items` (array) **(required)**: - `payments` (array) **(required)**: ### 404: Invoice not found or does not belong to this clinic - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/clinic-finances/invoices/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Clinic Credit Notes `GET https://api.guidelab.co/clinic-finances/credit-notes` Retrieve a paginated list of credit notes received by the authenticated clinic. Clinic-only. Supports filtering by status and search text. Documentation: https://docs.guidelab.co/api-reference/clinic-finances/listClinicCreditNotes ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `status` (string) (in: query): - `search` (string) (in: query): - `sortBy` (string) (in: query): Values: `createdAt`, `issueDate`, `creditNoteNumber`, `totalAmount` Default: `createdAt` - `sortOrder` (string) (in: query): Values: `asc`, `desc` Default: `desc` ## Responses ### 200: Paginated list of credit notes with lab details - `data` (array) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid or malformed query parameters - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/clinic-finances/credit-notes" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Clinic Credit Note `GET https://api.guidelab.co/clinic-finances/credit-notes/{id}` Retrieve full credit note details including line items and allocations. Clinic-only. Only returns credit notes belonging to the authenticated clinic. Documentation: https://docs.guidelab.co/api-reference/clinic-finances/getClinicCreditNote ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Credit note ID ## Responses ### 200: Full credit note detail with items and allocations - `id` (string) **(required)**: - `creditNoteNumber` (string) **(required)**: - `status` (string) **(required)**: - `items` (array) **(required)**: - `allocations` (array) **(required)**: ### 404: Credit note not found or does not belong to this clinic - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/clinic-finances/credit-notes/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Clinic Statements `GET https://api.guidelab.co/clinic-finances/statements` Retrieve a paginated list of statements received by the authenticated clinic. Clinic-only. Supports filtering by status and search text. Documentation: https://docs.guidelab.co/api-reference/clinic-finances/listClinicStatements ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `status` (string) (in: query): - `search` (string) (in: query): - `sortBy` (string) (in: query): Values: `createdAt`, `periodStart`, `statementNumber`, `totalDue` Default: `createdAt` - `sortOrder` (string) (in: query): Values: `asc`, `desc` Default: `desc` ## Responses ### 200: Paginated list of statements with lab details - `data` (array) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid or malformed query parameters - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/clinic-finances/statements" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Clinic Statement `GET https://api.guidelab.co/clinic-finances/statements/{id}` Retrieve full statement details including line items and balance breakdown. Clinic-only. Only returns statements belonging to the authenticated clinic. Documentation: https://docs.guidelab.co/api-reference/clinic-finances/getClinicStatement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Statement ID ## Responses ### 200: Full statement detail with line items and aged balances - `id` (string) **(required)**: - `statementNumber` (string) **(required)**: - `status` (string) **(required)**: - `lineItems` (array) **(required)**: ### 404: Statement not found or does not belong to this clinic - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/clinic-finances/statements/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Clinic Stripe Status `GET https://api.guidelab.co/clinic-finances/stripe-status/{labId}` Check whether a specific lab has Stripe Connect enabled and can accept online payments. Clinic-only. Used to determine if the pay-online option should be shown. Documentation: https://docs.guidelab.co/api-reference/clinic-finances/getClinicStripeStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `labId` (string) **(required)** (in: path): Lab ID to check Stripe status for - `partnershipId` (string) **(required)** (in: query): Exact partnership/account epoch authorizing this check ## Responses ### 200: Stripe enablement status for the specified lab - `stripeEnabled` (boolean) **(required)**: - `labStripeAccountId` (string,null) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/clinic-finances/stripe-status/{labId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Clinic Payment Stripe Receipt `GET https://api.guidelab.co/clinic-finances/payments/{paymentId}/receipt` Resolve the Stripe-hosted receipt URL for one of the clinic's Stripe payments. Fetched on demand from the lab's connected account (one Stripe read per call) so the link always reflects later refunds. Clinic-only. Documentation: https://docs.guidelab.co/api-reference/clinic-finances/getClinicPaymentStripeReceipt ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `paymentId` (string) **(required)** (in: path): Payment ID ## Responses ### 200: Stripe receipt URL - `url` (string) **(required)**: ### 404: No Stripe receipt exists for this payment - `error` (string) **(required)**: ### 502: Stripe could not be reached - `error` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/clinic-finances/payments/{paymentId}/receipt" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Clinic Finances Summary `GET https://api.guidelab.co/clinic-finances/summary` Aggregate outstanding-balance summary for the authenticated clinic across all payable invoices (not page-limited), broken down per lab for grouped Stripe payment. Clinic-only. Documentation: https://docs.guidelab.co/api-reference/clinic-finances/getClinicFinancesSummary ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Outstanding totals, overdue totals, and per-lab payable breakdown with Stripe status - `outstandingCount` (integer) **(required)**: - `overdueCount` (integer) **(required)**: - `currencyTotals` (object[]) **(required)**: - `currency` (string) **(required)**: Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `totalOutstanding` (string) **(required)**: - `overdueTotal` (string) **(required)**: - `outstandingCount` (integer) **(required)**: - `overdueCount` (integer) **(required)**: - `labs` (object[]) **(required)**: - `labId` (string) **(required)**: - `partnershipId` (string) **(required)**: - `labName` (string) **(required)**: - `labNameMissing` (boolean) **(required)**: - `outstandingTotal` (string) **(required)**: - `invoiceCount` (integer) **(required)**: - `overdueTotal` (string) **(required)**: - `overdueCount` (integer) **(required)**: - `currency` (string) **(required)**: Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `stripeEnabled` (boolean) **(required)**: - `labStripeAccountId` (string,null) **(required)**: - `invoiceIds` (string[]) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/clinic-finances/summary" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List products `GET https://api.guidelab.co/products` Retrieve a paginated list of products for the authenticated lab, grouped by category. Supports batch fetch by IDs, filtering by category/standard/search, and sorting. Includes file requirements, materials, inventory requirements, and custom fields. Documentation: https://docs.guidelab.co/api-reference/products/listProducts ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `ids` (string) (in: query): - `categoryId` (string) (in: query): - `standardId` (string) (in: query): - `search` (string) (in: query): - `includeInactive` (string) (in: query): - `includeHidden` (string) (in: query): - `onlyInactive` (string) (in: query): - `page` (string) (in: query): - `limit` (string) (in: query): - `sortBy` (string) (in: query): - `sortOrder` (string) (in: query): - `labId` (string) (in: query): - `clinicId` (string) (in: query): Lab viewers only: price the products for this customer, as the order will be charged. ## Responses ### 200: Paginated list of products with categories, materials, and custom fields - `categories` (array): - `products` (array): - `data` (array): - `workTypeLayout` (string): - `pagination` (object): - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 403: User does not have permission to access products ### 404: Not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/products" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a product `POST https://api.guidelab.co/products` Create a new product in the lab's catalog. Supports setting category, quality standard, treatment phase, pricing, materials, file requirements, inventory requirements, and custom fields in a single request. Documentation: https://docs.guidelab.co/api-reference/products/createProduct ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `sku` (string,null): - `description` (string,null): - `categoryId` (string,null): - `standardId` (string,null): - `treatmentPhaseId` (string) **(required)**: - `defaultPrice` (string,null): - `cogs` (string,null): - `pricingUnit` (string): (default: `product`) Values: `product`, `tooth`, `arch` - `priceBands` (array,null): - `minCount` (integer) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `priceBandsPerArch` (boolean): (default: `false`) - `implantSurcharge` (string,null): - `ponticSurcharge` (string,null): - `taxRate` (string,null): - `turnaroundDays` (integer): - `weight` (number,null): - `minTeethCount` (integer,null): - `maxTeethCount` (integer,null): - `teethLimitsPerArch` (boolean): (default: `false`) - `shadeEnabled` (boolean): (default: `true`) - `implantSpecRequired` (boolean): (default: `false`) - `archSelection` (string,null): Values: `upper`, `lower`, `both`, `single`, `null` - `bothArchesOnly` (boolean): (default: `false`) - `hideOdontogram` (boolean): (default: `false`) - `odontogramMode` (string): (default: `any_any`) Values: `single_natural`, `single_implant`, `single_any`, `bridge_natural`, `bridge_implant`, `bridge_any`, `any_natural`, `any_implant`, `any_any` - `configuratorType` (string): (default: `step_by_step`) Values: `single_page`, `step_by_step` - `askMaterialLast` (boolean): (default: `false`) - `quantityEnabled` (boolean): (default: `false`) - `autoAddToCart` (boolean): (default: `false`) - `upfrontPayment` (boolean): (default: `false`) - `isHidden` (boolean): (default: `false`) - `useProgressBar` (boolean): (default: `false`) - `hidePrice` (boolean): (default: `false`) - `surgeryDatePolicy` (string): (default: `off`) Values: `off`, `optional`, `required` - `surgeryDateHidesDueDate` (boolean): (default: `false`) - `fulfillmentMode` (string): (default: `physical`) Values: `physical`, `digital_only` - `isActive` (boolean): (default: `true`) - `sortOrder` (integer): (default: `0`) - `laboratoryCode` (string,null): - `laboratoryDescription` (string,null): - `productMaterials` (object[]): - `materialId` (string) **(required)**: - `isDefault` (boolean): (default: `false`) - `markupType` (string): (default: `value`) Values: `percentage`, `value` - `markupPercent` (string,null): - `markupValue` (string,null): - `priceBands` (array,null): - `minCount` (integer) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `fileRequirements` (object[]): - `id` (string): - `fileRequirementId` (string) **(required)**: - `requirementMode` (string): (default: `always_required`) Values: `always_required`, `conditionally_required`, `optional` - `requirementRules` (object,null): - `conditions` (object[]) **(required)**: - `field` (string) **(required)**: - `operator` (string) **(required)**: Values: `equals`, `not_empty`, `has_any`, `includes_any`, `includes_all` - `value` (object): - `fallback` (string) **(required)**: Values: `show_optional`, `hide` - `sortOrder` (integer): (default: `0`) - `inventoryRequirements` (object[]): - `inventoryItemId` (string) **(required)**: - `quantityPerUnit` (number) **(required)**: - `notes` (string): - `customFields` (object[]): - `id` (string): - `label` (string) **(required)**: - `fieldType` (string) **(required)**: Values: `input`, `textarea`, `odontogram`, `checkbox`, `select`, `radio`, `switch`, `file`, `number`, `date`, `image_select`, `image_multi_select` - `description` (string): - `placeholder` (string): - `defaultValue` (object): - `requirementMode` (string): (default: `optional`) Values: `always_required`, `conditionally_required`, `optional` - `requirementRules` (object,null): - `conditions` (object[]) **(required)**: - `field` (string) **(required)**: - `operator` (string) **(required)**: Values: `equals`, `not_empty`, `has_any`, `includes_any`, `includes_all`, `has_natural`, `has_implant`, `has_single`, `has_bridge` - `value` (object): - `fallback` (string) **(required)**: Values: `show_optional`, `hide` - `sortOrder` (integer): (default: `0`) - `options` (object[]): - `value` (string) **(required)**: - `label` (string) **(required)**: - `priceModifier` (string): - `turnaroundModifier` (integer): - `imageKey` (string): - `visibilityRules` (object,null): - `logic` (string): (default: `and`) Values: `and`, `or` - `conditions` (object[]) **(required)**: - `field` (string) **(required)**: - `operator` (string) **(required)**: Values: `equals`, `not_equals`, `contains`, `not_empty`, `is_empty`, `has_any`, `includes_any`, `includes_all`, `has_natural`, `has_implant`, `has_single`, `has_bridge` - `value` (object): - `action` (string): Values: `hide`, `disable` - `fieldConfig` (object): - `isActive` (boolean): (default: `true`) - `triggerRules` (array,null): - `id` (string) **(required)**: - `targetProductId` (string) **(required)**: - `quantity` (integer): (default: `1`) - `rules` (object) **(required)**: - `logic` (string): (default: `and`) Values: `and`, `or` - `conditions` (object[]) **(required)**: - `field` (string) **(required)**: - `operator` (string) **(required)**: Values: `equals`, `not_equals`, `contains`, `not_empty`, `is_empty`, `has_any`, `includes_any`, `includes_all`, `has_natural`, `has_implant`, `has_single`, `has_bridge` - `value` (object): - `action` (string): Values: `hide`, `disable` - `enabled` (boolean): (default: `true`) - `duplicateFromProductId` (string): [uuid] ## Responses ### 201: Product successfully created - `product` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `standardId` (string,null) **(required)**: - `treatmentPhaseId` (string) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `description` (string,null) **(required)**: - `defaultPrice` (string,null) **(required)**: - `cogs` (string,null) **(required)**: - `pricingUnit` (string) **(required)**: - `priceBands` (array,null) **(required)**: - `minCount` (number) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `priceBandsPerArch` (boolean) **(required)**: - `implantSurcharge` (string,null) **(required)**: - `ponticSurcharge` (string,null) **(required)**: - `taxRate` (string,null) **(required)**: - `turnaroundDays` (number,null) **(required)**: - `weight` (string,null) **(required)**: - `minTeethCount` (number,null) **(required)**: - `maxTeethCount` (number,null) **(required)**: - `teethLimitsPerArch` (boolean) **(required)**: - `shadeEnabled` (boolean) **(required)**: - `implantSpecRequired` (boolean) **(required)**: - `archSelection` (string,null) **(required)**: - `bothArchesOnly` (boolean) **(required)**: - `hideOdontogram` (boolean) **(required)**: - `odontogramMode` (string) **(required)**: - `configuratorType` (string) **(required)**: Values: `single_page`, `step_by_step` - `askMaterialLast` (boolean) **(required)**: - `quantityEnabled` (boolean) **(required)**: - `autoAddToCart` (boolean) **(required)**: - `upfrontPayment` (boolean) **(required)**: - `isHidden` (boolean) **(required)**: - `useProgressBar` (boolean) **(required)**: - `hidePrice` (boolean) **(required)**: - `surgeryDatePolicy` (string) **(required)**: Values: `off`, `optional`, `required` - `surgeryDateHidesDueDate` (boolean) **(required)**: - `fulfillmentMode` (string) **(required)**: Values: `physical`, `digital_only` - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `laboratoryCode` (string,null) **(required)**: - `laboratoryDescription` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `triggerRules` (object): - `treatmentPhaseName` (string,null): - `treatmentPhaseSortOrder` (number,null): - `treatmentPhaseStartPolicy` (string,null): - `treatmentPhaseLeadTimeDays` (number,null): - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 403: Only labs can create products ### 404: Category, standard, treatment phase, or inventory item not found ### 409: A product with this SKU already exists or the same image copy is in progress ### 413: Copied option images exceed the size budget ### 429: Product image copy budget exceeded ### 500: Internal server error ### 504: Product option image copy timed out ## Example ```bash curl -X POST "https://api.guidelab.co/products" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "treatmentPhaseId": "string" }' ``` --- # List recent custom field templates `GET https://api.guidelab.co/products/recent-custom-fields` Return up to 100 of the most recently added custom field templates across the authenticated lab's products, deduped by (label, fieldType). Used by the product editor's Quick Add picker. Documentation: https://docs.guidelab.co/api-reference/products/listRecentCustomFields ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Recent custom field templates - `fields` (array) **(required)**: ### 403: Only labs can list custom field templates ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/products/recent-custom-fields" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List product picker options `GET https://api.guidelab.co/products/options` Return the authenticated lab's products as `id`/`name`/`sku` picker options from a single projection, without the categories, materials, custom fields and file requirements the paginated list carries. Capped at 1000 rows; `truncated` reports when the lab holds more. Documentation: https://docs.guidelab.co/api-reference/products/listProductOptions ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` (string) (in: query): - `includeHidden` (string) (in: query): - `search` (string) (in: query): ## Responses ### 200: Product picker options - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `truncated` (boolean) **(required)**: ### 400: Invalid query parameters ### 403: Only labs can list product options ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/products/options" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get a product `GET https://api.guidelab.co/products/{id}` Retrieve a single product of the authenticated lab by its ID, including its category, quality standard, materials, file requirements, inventory requirements, and custom fields. Customers read products through the priced catalog list instead. Documentation: https://docs.guidelab.co/api-reference/products/getProduct ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Product ID ## Responses ### 200: Product details with all related data - `product` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `standardId` (string,null) **(required)**: - `treatmentPhaseId` (string) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `description` (string,null) **(required)**: - `defaultPrice` (string,null) **(required)**: - `cogs` (string,null) **(required)**: - `pricingUnit` (string) **(required)**: - `priceBands` (array,null) **(required)**: - `minCount` (number) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `priceBandsPerArch` (boolean) **(required)**: - `implantSurcharge` (string,null) **(required)**: - `ponticSurcharge` (string,null) **(required)**: - `taxRate` (string,null) **(required)**: - `turnaroundDays` (number,null) **(required)**: - `weight` (string,null) **(required)**: - `minTeethCount` (number,null) **(required)**: - `maxTeethCount` (number,null) **(required)**: - `teethLimitsPerArch` (boolean) **(required)**: - `shadeEnabled` (boolean) **(required)**: - `implantSpecRequired` (boolean) **(required)**: - `archSelection` (string,null) **(required)**: - `bothArchesOnly` (boolean) **(required)**: - `hideOdontogram` (boolean) **(required)**: - `odontogramMode` (string) **(required)**: - `configuratorType` (string) **(required)**: Values: `single_page`, `step_by_step` - `askMaterialLast` (boolean) **(required)**: - `quantityEnabled` (boolean) **(required)**: - `autoAddToCart` (boolean) **(required)**: - `upfrontPayment` (boolean) **(required)**: - `isHidden` (boolean) **(required)**: - `useProgressBar` (boolean) **(required)**: - `hidePrice` (boolean) **(required)**: - `surgeryDatePolicy` (string) **(required)**: Values: `off`, `optional`, `required` - `surgeryDateHidesDueDate` (boolean) **(required)**: - `fulfillmentMode` (string) **(required)**: Values: `physical`, `digital_only` - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `laboratoryCode` (string,null) **(required)**: - `laboratoryDescription` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `triggerRules` (object): - `treatmentPhaseName` (string,null): - `treatmentPhaseSortOrder` (number,null): - `treatmentPhaseStartPolicy` (string,null): - `treatmentPhaseLeadTimeDays` (number,null): - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `category` (object,null) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `standard` (object,null) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `code` (string) **(required)**: - `productMaterials` (array) **(required)**: - `fileRequirements` (array) **(required)**: - `customFields` (array) **(required)**: - `inventoryRequirements` (array) **(required)**: ### 400: Invalid request ### 403: User does not have permission to view this product ### 404: Product not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/products/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Partially update a product `PATCH https://api.guidelab.co/products/{id}` Partially update a product's flags such as isHidden, isActive, or sortOrder. Supports action-based toggles (toggleHidden, toggleActive) or direct field updates. Documentation: https://docs.guidelab.co/api-reference/products/patchProduct ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Product ID ## Request Body Content-Type: `application/json` - `action` (string): Values: `toggleHidden`, `toggleActive` - `isHidden` (boolean): - `isActive` (boolean): - `sortOrder` (integer): ## Responses ### 200: Product partially updated - `product` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `standardId` (string,null) **(required)**: - `treatmentPhaseId` (string) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `description` (string,null) **(required)**: - `defaultPrice` (string,null) **(required)**: - `cogs` (string,null) **(required)**: - `pricingUnit` (string) **(required)**: - `priceBands` (array,null) **(required)**: - `minCount` (number) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `priceBandsPerArch` (boolean) **(required)**: - `implantSurcharge` (string,null) **(required)**: - `ponticSurcharge` (string,null) **(required)**: - `taxRate` (string,null) **(required)**: - `turnaroundDays` (number,null) **(required)**: - `weight` (string,null) **(required)**: - `minTeethCount` (number,null) **(required)**: - `maxTeethCount` (number,null) **(required)**: - `teethLimitsPerArch` (boolean) **(required)**: - `shadeEnabled` (boolean) **(required)**: - `implantSpecRequired` (boolean) **(required)**: - `archSelection` (string,null) **(required)**: - `bothArchesOnly` (boolean) **(required)**: - `hideOdontogram` (boolean) **(required)**: - `odontogramMode` (string) **(required)**: - `configuratorType` (string) **(required)**: Values: `single_page`, `step_by_step` - `askMaterialLast` (boolean) **(required)**: - `quantityEnabled` (boolean) **(required)**: - `autoAddToCart` (boolean) **(required)**: - `upfrontPayment` (boolean) **(required)**: - `isHidden` (boolean) **(required)**: - `useProgressBar` (boolean) **(required)**: - `hidePrice` (boolean) **(required)**: - `surgeryDatePolicy` (string) **(required)**: Values: `off`, `optional`, `required` - `surgeryDateHidesDueDate` (boolean) **(required)**: - `fulfillmentMode` (string) **(required)**: Values: `physical`, `digital_only` - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `laboratoryCode` (string,null) **(required)**: - `laboratoryDescription` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `triggerRules` (object): - `treatmentPhaseName` (string,null): - `treatmentPhaseSortOrder` (number,null): - `treatmentPhaseStartPolicy` (string,null): - `treatmentPhaseLeadTimeDays` (number,null): - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request ### 403: Only labs can update products ### 404: Product not found ### 500: Internal server error ## Example ```bash curl -X PATCH "https://api.guidelab.co/products/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "action": "toggleHidden", "isHidden": true, "isActive": true, "sortOrder": 0 }' ``` --- # Delete a product `DELETE https://api.guidelab.co/products/{id}` Soft-delete a product by setting it to inactive. The product record is preserved for historical reference in existing orders. Documentation: https://docs.guidelab.co/api-reference/products/deleteProduct ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Product ID ## Responses ### 200: Product deactivated successfully - `product` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `standardId` (string,null) **(required)**: - `treatmentPhaseId` (string) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `description` (string,null) **(required)**: - `defaultPrice` (string,null) **(required)**: - `cogs` (string,null) **(required)**: - `pricingUnit` (string) **(required)**: - `priceBands` (array,null) **(required)**: - `minCount` (number) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `priceBandsPerArch` (boolean) **(required)**: - `implantSurcharge` (string,null) **(required)**: - `ponticSurcharge` (string,null) **(required)**: - `taxRate` (string,null) **(required)**: - `turnaroundDays` (number,null) **(required)**: - `weight` (string,null) **(required)**: - `minTeethCount` (number,null) **(required)**: - `maxTeethCount` (number,null) **(required)**: - `teethLimitsPerArch` (boolean) **(required)**: - `shadeEnabled` (boolean) **(required)**: - `implantSpecRequired` (boolean) **(required)**: - `archSelection` (string,null) **(required)**: - `bothArchesOnly` (boolean) **(required)**: - `hideOdontogram` (boolean) **(required)**: - `odontogramMode` (string) **(required)**: - `configuratorType` (string) **(required)**: Values: `single_page`, `step_by_step` - `askMaterialLast` (boolean) **(required)**: - `quantityEnabled` (boolean) **(required)**: - `autoAddToCart` (boolean) **(required)**: - `upfrontPayment` (boolean) **(required)**: - `isHidden` (boolean) **(required)**: - `useProgressBar` (boolean) **(required)**: - `hidePrice` (boolean) **(required)**: - `surgeryDatePolicy` (string) **(required)**: Values: `off`, `optional`, `required` - `surgeryDateHidesDueDate` (boolean) **(required)**: - `fulfillmentMode` (string) **(required)**: Values: `physical`, `digital_only` - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `laboratoryCode` (string,null) **(required)**: - `laboratoryDescription` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `triggerRules` (object): - `treatmentPhaseName` (string,null): - `treatmentPhaseSortOrder` (number,null): - `treatmentPhaseStartPolicy` (string,null): - `treatmentPhaseLeadTimeDays` (number,null): - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `message` (string) **(required)**: ### 400: Invalid request ### 403: Only labs can delete products ### 404: Product not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/products/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a product `PUT https://api.guidelab.co/products/{id}` Update an existing product's properties, materials, file requirements, inventory requirements, and custom fields. File requirements referenced by existing files are soft-deleted (archived) rather than permanently removed. Documentation: https://docs.guidelab.co/api-reference/products/updateProduct ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Product ID ## Request Body Content-Type: `application/json` - `name` (string): - `sku` (string,null): - `description` (string,null): - `categoryId` (string,null): - `standardId` (string,null): - `treatmentPhaseId` (string): - `defaultPrice` (string,null): - `cogs` (string,null): - `pricingUnit` (string): (default: `product`) Values: `product`, `tooth`, `arch` - `priceBands` (array,null): - `minCount` (integer) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `priceBandsPerArch` (boolean): (default: `false`) - `implantSurcharge` (string,null): - `ponticSurcharge` (string,null): - `taxRate` (string,null): - `turnaroundDays` (integer): - `weight` (number,null): - `minTeethCount` (integer,null): - `maxTeethCount` (integer,null): - `teethLimitsPerArch` (boolean): - `shadeEnabled` (boolean): (default: `true`) - `implantSpecRequired` (boolean): (default: `false`) - `archSelection` (string,null): Values: `upper`, `lower`, `both`, `single`, `null` - `bothArchesOnly` (boolean): (default: `false`) - `hideOdontogram` (boolean): (default: `false`) - `odontogramMode` (string): (default: `any_any`) Values: `single_natural`, `single_implant`, `single_any`, `bridge_natural`, `bridge_implant`, `bridge_any`, `any_natural`, `any_implant`, `any_any` - `configuratorType` (string): (default: `step_by_step`) Values: `single_page`, `step_by_step` - `askMaterialLast` (boolean): (default: `false`) - `quantityEnabled` (boolean): (default: `false`) - `autoAddToCart` (boolean): (default: `false`) - `upfrontPayment` (boolean): (default: `false`) - `isHidden` (boolean): (default: `false`) - `useProgressBar` (boolean): (default: `false`) - `hidePrice` (boolean): (default: `false`) - `surgeryDatePolicy` (string): (default: `off`) Values: `off`, `optional`, `required` - `surgeryDateHidesDueDate` (boolean): (default: `false`) - `fulfillmentMode` (string): (default: `physical`) Values: `physical`, `digital_only` - `isActive` (boolean): (default: `true`) - `sortOrder` (integer): (default: `0`) - `laboratoryCode` (string,null): - `laboratoryDescription` (string,null): - `productMaterials` (object[]): - `materialId` (string) **(required)**: - `isDefault` (boolean): (default: `false`) - `markupType` (string): (default: `value`) Values: `percentage`, `value` - `markupPercent` (string,null): - `markupValue` (string,null): - `priceBands` (array,null): - `minCount` (integer) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `fileRequirements` (object[]): - `id` (string): - `fileRequirementId` (string) **(required)**: - `requirementMode` (string): (default: `always_required`) Values: `always_required`, `conditionally_required`, `optional` - `requirementRules` (object,null): - `conditions` (object[]) **(required)**: - `field` (string) **(required)**: - `operator` (string) **(required)**: Values: `equals`, `not_empty`, `has_any`, `includes_any`, `includes_all` - `value` (object): - `fallback` (string) **(required)**: Values: `show_optional`, `hide` - `sortOrder` (integer): (default: `0`) - `inventoryRequirements` (object[]): - `inventoryItemId` (string) **(required)**: - `quantityPerUnit` (number) **(required)**: - `notes` (string): - `customFields` (object[]): - `id` (string): - `label` (string) **(required)**: - `fieldType` (string) **(required)**: Values: `input`, `textarea`, `odontogram`, `checkbox`, `select`, `radio`, `switch`, `file`, `number`, `date`, `image_select`, `image_multi_select` - `description` (string): - `placeholder` (string): - `defaultValue` (object): - `requirementMode` (string): (default: `optional`) Values: `always_required`, `conditionally_required`, `optional` - `requirementRules` (object,null): - `conditions` (object[]) **(required)**: - `field` (string) **(required)**: - `operator` (string) **(required)**: Values: `equals`, `not_empty`, `has_any`, `includes_any`, `includes_all`, `has_natural`, `has_implant`, `has_single`, `has_bridge` - `value` (object): - `fallback` (string) **(required)**: Values: `show_optional`, `hide` - `sortOrder` (integer): (default: `0`) - `options` (object[]): - `value` (string) **(required)**: - `label` (string) **(required)**: - `priceModifier` (string): - `turnaroundModifier` (integer): - `imageKey` (string): - `visibilityRules` (object,null): - `logic` (string): (default: `and`) Values: `and`, `or` - `conditions` (object[]) **(required)**: - `field` (string) **(required)**: - `operator` (string) **(required)**: Values: `equals`, `not_equals`, `contains`, `not_empty`, `is_empty`, `has_any`, `includes_any`, `includes_all`, `has_natural`, `has_implant`, `has_single`, `has_bridge` - `value` (object): - `action` (string): Values: `hide`, `disable` - `fieldConfig` (object): - `isActive` (boolean): (default: `true`) - `triggerRules` (array,null): - `id` (string) **(required)**: - `targetProductId` (string) **(required)**: - `quantity` (integer): (default: `1`) - `rules` (object) **(required)**: - `logic` (string): (default: `and`) Values: `and`, `or` - `conditions` (object[]) **(required)**: - `field` (string) **(required)**: - `operator` (string) **(required)**: Values: `equals`, `not_equals`, `contains`, `not_empty`, `is_empty`, `has_any`, `includes_any`, `includes_all`, `has_natural`, `has_implant`, `has_single`, `has_bridge` - `value` (object): - `action` (string): Values: `hide`, `disable` - `enabled` (boolean): (default: `true`) - `duplicateFromProductId` (string): [uuid] ## Responses ### 200: Product successfully updated - `product` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `standardId` (string,null) **(required)**: - `treatmentPhaseId` (string) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `description` (string,null) **(required)**: - `defaultPrice` (string,null) **(required)**: - `cogs` (string,null) **(required)**: - `pricingUnit` (string) **(required)**: - `priceBands` (array,null) **(required)**: - `minCount` (number) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `priceBandsPerArch` (boolean) **(required)**: - `implantSurcharge` (string,null) **(required)**: - `ponticSurcharge` (string,null) **(required)**: - `taxRate` (string,null) **(required)**: - `turnaroundDays` (number,null) **(required)**: - `weight` (string,null) **(required)**: - `minTeethCount` (number,null) **(required)**: - `maxTeethCount` (number,null) **(required)**: - `teethLimitsPerArch` (boolean) **(required)**: - `shadeEnabled` (boolean) **(required)**: - `implantSpecRequired` (boolean) **(required)**: - `archSelection` (string,null) **(required)**: - `bothArchesOnly` (boolean) **(required)**: - `hideOdontogram` (boolean) **(required)**: - `odontogramMode` (string) **(required)**: - `configuratorType` (string) **(required)**: Values: `single_page`, `step_by_step` - `askMaterialLast` (boolean) **(required)**: - `quantityEnabled` (boolean) **(required)**: - `autoAddToCart` (boolean) **(required)**: - `upfrontPayment` (boolean) **(required)**: - `isHidden` (boolean) **(required)**: - `useProgressBar` (boolean) **(required)**: - `hidePrice` (boolean) **(required)**: - `surgeryDatePolicy` (string) **(required)**: Values: `off`, `optional`, `required` - `surgeryDateHidesDueDate` (boolean) **(required)**: - `fulfillmentMode` (string) **(required)**: Values: `physical`, `digital_only` - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `laboratoryCode` (string,null) **(required)**: - `laboratoryDescription` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `triggerRules` (object): - `treatmentPhaseName` (string,null): - `treatmentPhaseSortOrder` (number,null): - `treatmentPhaseStartPolicy` (string,null): - `treatmentPhaseLeadTimeDays` (number,null): - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 403: Only labs can update products ### 404: Product, category, standard, phase, or inventory item not found ### 409: A product with this SKU already exists or the same image copy is in progress ### 413: Copied option images exceed the size budget ### 429: Product image copy budget exceeded ### 500: Internal server error ### 504: Product option image copy timed out ## Example ```bash curl -X PUT "https://api.guidelab.co/products/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Get product image `GET https://api.guidelab.co/products/{id}/image` Retrieve the image associated with a product from R2 storage. Available to the owning lab, its partner clinics, and, for active products of a discoverable lab, any clinic. Returns the raw image binary with appropriate content-type headers. Documentation: https://docs.guidelab.co/api-reference/products/getProductImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Product ID ## Responses ### 200: Product image binary data ## Example ```bash curl -X GET "https://api.guidelab.co/products/{id}/image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload product image `POST https://api.guidelab.co/products/{id}/image` Upload or replace the image for a product. Accepts JPEG, PNG, WebP, or GIF up to 5MB via multipart form data. Documentation: https://docs.guidelab.co/api-reference/products/uploadProductImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Product ID ## Responses ### 200: Product image successfully uploaded - `product` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `standardId` (string,null) **(required)**: - `treatmentPhaseId` (string) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `description` (string,null) **(required)**: - `defaultPrice` (string,null) **(required)**: - `cogs` (string,null) **(required)**: - `pricingUnit` (string) **(required)**: - `priceBands` (array,null) **(required)**: - `minCount` (number) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `priceBandsPerArch` (boolean) **(required)**: - `implantSurcharge` (string,null) **(required)**: - `ponticSurcharge` (string,null) **(required)**: - `taxRate` (string,null) **(required)**: - `turnaroundDays` (number,null) **(required)**: - `weight` (string,null) **(required)**: - `minTeethCount` (number,null) **(required)**: - `maxTeethCount` (number,null) **(required)**: - `teethLimitsPerArch` (boolean) **(required)**: - `shadeEnabled` (boolean) **(required)**: - `implantSpecRequired` (boolean) **(required)**: - `archSelection` (string,null) **(required)**: - `bothArchesOnly` (boolean) **(required)**: - `hideOdontogram` (boolean) **(required)**: - `odontogramMode` (string) **(required)**: - `configuratorType` (string) **(required)**: Values: `single_page`, `step_by_step` - `askMaterialLast` (boolean) **(required)**: - `quantityEnabled` (boolean) **(required)**: - `autoAddToCart` (boolean) **(required)**: - `upfrontPayment` (boolean) **(required)**: - `isHidden` (boolean) **(required)**: - `useProgressBar` (boolean) **(required)**: - `hidePrice` (boolean) **(required)**: - `surgeryDatePolicy` (string) **(required)**: Values: `off`, `optional`, `required` - `surgeryDateHidesDueDate` (boolean) **(required)**: - `fulfillmentMode` (string) **(required)**: Values: `physical`, `digital_only` - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `laboratoryCode` (string,null) **(required)**: - `laboratoryDescription` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `triggerRules` (object): - `treatmentPhaseName` (string,null): - `treatmentPhaseSortOrder` (number,null): - `treatmentPhaseStartPolicy` (string,null): - `treatmentPhaseLeadTimeDays` (number,null): - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid file type or file too large ### 403: Only labs can upload product images ### 404: Product not found ### 500: Internal server error or storage not configured ## Example ```bash curl -X POST "https://api.guidelab.co/products/{id}/image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete product image `DELETE https://api.guidelab.co/products/{id}/image` Remove the image associated with a product from R2 storage and clear the imageKey reference. Documentation: https://docs.guidelab.co/api-reference/products/deleteProductImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Product ID ## Responses ### 200: Product image successfully removed - `product` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `standardId` (string,null) **(required)**: - `treatmentPhaseId` (string) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `description` (string,null) **(required)**: - `defaultPrice` (string,null) **(required)**: - `cogs` (string,null) **(required)**: - `pricingUnit` (string) **(required)**: - `priceBands` (array,null) **(required)**: - `minCount` (number) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `priceBandsPerArch` (boolean) **(required)**: - `implantSurcharge` (string,null) **(required)**: - `ponticSurcharge` (string,null) **(required)**: - `taxRate` (string,null) **(required)**: - `turnaroundDays` (number,null) **(required)**: - `weight` (string,null) **(required)**: - `minTeethCount` (number,null) **(required)**: - `maxTeethCount` (number,null) **(required)**: - `teethLimitsPerArch` (boolean) **(required)**: - `shadeEnabled` (boolean) **(required)**: - `implantSpecRequired` (boolean) **(required)**: - `archSelection` (string,null) **(required)**: - `bothArchesOnly` (boolean) **(required)**: - `hideOdontogram` (boolean) **(required)**: - `odontogramMode` (string) **(required)**: - `configuratorType` (string) **(required)**: Values: `single_page`, `step_by_step` - `askMaterialLast` (boolean) **(required)**: - `quantityEnabled` (boolean) **(required)**: - `autoAddToCart` (boolean) **(required)**: - `upfrontPayment` (boolean) **(required)**: - `isHidden` (boolean) **(required)**: - `useProgressBar` (boolean) **(required)**: - `hidePrice` (boolean) **(required)**: - `surgeryDatePolicy` (string) **(required)**: Values: `off`, `optional`, `required` - `surgeryDateHidesDueDate` (boolean) **(required)**: - `fulfillmentMode` (string) **(required)**: Values: `physical`, `digital_only` - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `laboratoryCode` (string,null) **(required)**: - `laboratoryDescription` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `triggerRules` (object): - `treatmentPhaseName` (string,null): - `treatmentPhaseSortOrder` (number,null): - `treatmentPhaseStartPolicy` (string,null): - `treatmentPhaseLeadTimeDays` (number,null): - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `message` (string) **(required)**: ### 400: Product has no image ### 403: Only labs can delete product images ### 404: Product not found ### 500: Internal server error or storage not configured ## Example ```bash curl -X DELETE "https://api.guidelab.co/products/{id}/image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get custom field image `GET https://api.guidelab.co/products/{id}/custom-field-image` Retrieve a custom field option image from R2 storage by its key. Validates that the image key belongs to the authenticated organization. Documentation: https://docs.guidelab.co/api-reference/products/getCustomFieldImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Product ID - `key` (string) (in: query): ## Responses ### 200: Custom field image binary data ## Example ```bash curl -X GET "https://api.guidelab.co/products/{id}/custom-field-image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload custom field image `POST https://api.guidelab.co/products/{id}/custom-field-image` Upload an image for a product custom field option (e.g. image_select or image_multi_select). Accepts JPEG, PNG, WebP, or GIF up to 5MB via multipart form data with a fieldId. Documentation: https://docs.guidelab.co/api-reference/products/uploadCustomFieldImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Product ID ## Responses ### 200: Custom field image successfully uploaded with imageKey - `imageKey` (string) **(required)**: ### 400: Invalid file type, file too large, or missing fieldId ### 403: Only labs can upload custom field images ### 404: Product not found ### 500: Internal server error or storage not configured ## Example ```bash curl -X POST "https://api.guidelab.co/products/{id}/custom-field-image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete custom field image `DELETE https://api.guidelab.co/products/{id}/custom-field-image` Remove a custom field option image from R2 storage. Validates that the image key belongs to the authenticated organization. Documentation: https://docs.guidelab.co/api-reference/products/deleteCustomFieldImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Product ID ## Request Body Content-Type: `application/json` - `imageKey` (string) **(required)**: ## Responses ### 200: Custom field image successfully removed - `message` (string) **(required)**: ### 400: Missing image key ### 403: Only labs can delete custom field images or image does not belong to this organization ### 404: Not found ### 500: Internal server error or storage not configured ## Example ```bash curl -X DELETE "https://api.guidelab.co/products/{id}/custom-field-image" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "imageKey": "string" }' ``` --- # List categories `GET https://api.guidelab.co/categories` Retrieve product categories for the authenticated lab, optionally filtered by parent or active status. Returns a hierarchical tree by default or a flat list when requested. Documentation: https://docs.guidelab.co/api-reference/categories/listCategories ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` () (in: query): Default: `false` - `parentId` (string) (in: query): - `flat` () (in: query): Default: `false` - `labId` (string) (in: query): ## Responses ### 200: Successfully retrieved the list of product categories - `categories` (array) **(required)**: ### 400: Invalid query parameters ### 403: User does not have permission to access categories ### 404: Lab not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/categories" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a category `POST https://api.guidelab.co/categories` Create a new product category for the authenticated lab. Categories can be nested one level deep by specifying a parentId. Documentation: https://docs.guidelab.co/api-reference/categories/createCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `subtitle` (string): - `description` (string): - `parentId` (string): - `icon` (string): - `imageAspectRatio` (string): (default: `square`) Values: `square`, `wide` - `guideTitle` (string): - `guideBody` (string): - `sortOrder` (integer): (default: `0`) - `isActive` (boolean): (default: `true`) ## Responses ### 201: Category successfully created - `category` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `parentId` (string,null) **(required)**: - `name` (string) **(required)**: - `subtitle` (string,null) **(required)**: - `description` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `imageAspectRatio` (string) **(required)**: Values: `square`, `wide` - `guideTitle` (string,null) **(required)**: - `guideBody` (string,null) **(required)**: - `guideMediaKey` (string,null) **(required)**: - `guideMediaType` (string,null) **(required)**: Values: `image`, `video`, `null` - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body or nesting depth exceeded ### 403: Only labs can create categories ### 404: Parent category not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/categories" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string" }' ``` --- # Reorder categories `POST https://api.guidelab.co/categories/reorder` Bulk update the sort order and parent assignments for product categories. Validates nesting depth constraints (max one level deep). Documentation: https://docs.guidelab.co/api-reference/categories/reorderCategories ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `categories` (object[]) **(required)**: - `id` (string) **(required)**: - `parentId` (string,null) **(required)**: - `sortOrder` (integer) **(required)**: ## Responses ### 200: Categories successfully reordered - `success` (boolean) **(required)**: ### 400: Invalid nesting or request body ### 403: Only labs can reorder categories ### 404: One or more categories not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/categories/reorder" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "categories": [ { "id": "string", "parentId": "string", "sortOrder": 0 } ] }' ``` --- # Get a category `GET https://api.guidelab.co/categories/{id}` Retrieve a single product category by its ID. Clinic users must have an active partnership with the owning lab. Documentation: https://docs.guidelab.co/api-reference/categories/getCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Category ID ## Responses ### 200: Category details - `category` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `parentId` (string,null) **(required)**: - `name` (string) **(required)**: - `subtitle` (string,null) **(required)**: - `description` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `imageAspectRatio` (string) **(required)**: Values: `square`, `wide` - `guideTitle` (string,null) **(required)**: - `guideBody` (string,null) **(required)**: - `guideMediaKey` (string,null) **(required)**: - `guideMediaType` (string,null) **(required)**: Values: `image`, `video`, `null` - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request ### 403: User does not have permission to view this category ### 404: Category not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/categories/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Toggle category active status `PATCH https://api.guidelab.co/categories/{id}` Toggle the active/inactive status of a product category. Documentation: https://docs.guidelab.co/api-reference/categories/toggleCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Category ID ## Responses ### 200: Category active status toggled - `category` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `parentId` (string,null) **(required)**: - `name` (string) **(required)**: - `subtitle` (string,null) **(required)**: - `description` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `imageAspectRatio` (string) **(required)**: Values: `square`, `wide` - `guideTitle` (string,null) **(required)**: - `guideBody` (string,null) **(required)**: - `guideMediaKey` (string,null) **(required)**: - `guideMediaType` (string,null) **(required)**: Values: `image`, `video`, `null` - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request ### 403: Only labs can toggle categories ### 404: Category not found ### 500: Internal server error ## Example ```bash curl -X PATCH "https://api.guidelab.co/categories/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete a category `DELETE https://api.guidelab.co/categories/{id}` Delete a product category. If the category has associated products or bundles, it is soft-deleted (deactivated) instead of permanently removed. Documentation: https://docs.guidelab.co/api-reference/categories/deleteCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Category ID ## Responses ### 200: Category deleted or deactivated - `category` (object): - `id` (string) **(required)**: - `labId` (string) **(required)**: - `parentId` (string,null) **(required)**: - `name` (string) **(required)**: - `subtitle` (string,null) **(required)**: - `description` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `imageAspectRatio` (string) **(required)**: Values: `square`, `wide` - `guideTitle` (string,null) **(required)**: - `guideBody` (string,null) **(required)**: - `guideMediaKey` (string,null) **(required)**: - `guideMediaType` (string,null) **(required)**: Values: `image`, `video`, `null` - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `action` (string) **(required)**: - `message` (string) **(required)**: ### 400: Invalid request ### 403: Only labs can delete categories ### 404: Category not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/categories/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a category `PUT https://api.guidelab.co/categories/{id}` Update an existing product category. Validates nesting constraints if parentId is changed. Documentation: https://docs.guidelab.co/api-reference/categories/updateCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Category ID ## Request Body Content-Type: `application/json` - `name` (string): - `subtitle` (string): - `description` (string): - `parentId` (string): - `icon` (string): - `imageAspectRatio` (string): Values: `square`, `wide` - `guideTitle` (string): - `guideBody` (string): - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 200: Category successfully updated - `category` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `parentId` (string,null) **(required)**: - `name` (string) **(required)**: - `subtitle` (string,null) **(required)**: - `description` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `imageAspectRatio` (string) **(required)**: Values: `square`, `wide` - `guideTitle` (string,null) **(required)**: - `guideBody` (string,null) **(required)**: - `guideMediaKey` (string,null) **(required)**: - `guideMediaType` (string,null) **(required)**: Values: `image`, `video`, `null` - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body or self-referencing parent ### 403: Only labs can update categories ### 404: Category or parent category not found ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/categories/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Get category image `GET https://api.guidelab.co/categories/{id}/image` Retrieve the image associated with a product category from R2 storage. Available to the owning lab, its partner clinics, and, for active categories of a discoverable lab, any clinic. Returns the raw image binary with appropriate content-type headers. Documentation: https://docs.guidelab.co/api-reference/categories/getCategoryImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Category ID ## Responses ### 200: Category image binary data ## Example ```bash curl -X GET "https://api.guidelab.co/categories/{id}/image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload category image `POST https://api.guidelab.co/categories/{id}/image` Upload or replace the image for a product category. Accepts JPEG, PNG, WebP, or GIF up to 5MB via multipart form data. Documentation: https://docs.guidelab.co/api-reference/categories/uploadCategoryImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Category ID ## Responses ### 200: Image successfully uploaded - `category` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `parentId` (string,null) **(required)**: - `name` (string) **(required)**: - `subtitle` (string,null) **(required)**: - `description` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `imageAspectRatio` (string) **(required)**: Values: `square`, `wide` - `guideTitle` (string,null) **(required)**: - `guideBody` (string,null) **(required)**: - `guideMediaKey` (string,null) **(required)**: - `guideMediaType` (string,null) **(required)**: Values: `image`, `video`, `null` - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid file type or file too large ### 403: Only labs can upload category images ### 404: Category not found ### 500: Internal server error or storage not configured ## Example ```bash curl -X POST "https://api.guidelab.co/categories/{id}/image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete category image `DELETE https://api.guidelab.co/categories/{id}/image` Remove the image associated with a product category from R2 storage and clear the imageKey reference. Documentation: https://docs.guidelab.co/api-reference/categories/deleteCategoryImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Category ID ## Responses ### 200: Category image successfully removed - `category` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `parentId` (string,null) **(required)**: - `name` (string) **(required)**: - `subtitle` (string,null) **(required)**: - `description` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `imageAspectRatio` (string) **(required)**: Values: `square`, `wide` - `guideTitle` (string,null) **(required)**: - `guideBody` (string,null) **(required)**: - `guideMediaKey` (string,null) **(required)**: - `guideMediaType` (string,null) **(required)**: Values: `image`, `video`, `null` - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `message` (string) **(required)**: ### 400: Category has no image ### 403: Only labs can delete category images ### 404: Category not found ### 500: Internal server error or storage not configured ## Example ```bash curl -X DELETE "https://api.guidelab.co/categories/{id}/image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get category guide media `GET https://api.guidelab.co/categories/{id}/guide-media` Retrieve the decision-guide media (image or video) for a product category from R2 storage. Returns the raw binary with appropriate content-type headers. Documentation: https://docs.guidelab.co/api-reference/categories/getCategoryGuideMedia ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Category ID ## Responses ### 200: Guide media binary data ## Example ```bash curl -X GET "https://api.guidelab.co/categories/{id}/guide-media" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload category guide media `POST https://api.guidelab.co/categories/{id}/guide-media` Upload or replace the decision-guide media for a product category. Accepts image (JPEG/PNG/WebP/GIF up to 5MB) or video (MP4/WebM up to 20MB) via multipart form data. Documentation: https://docs.guidelab.co/api-reference/categories/uploadCategoryGuideMedia ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Category ID ## Responses ### 200: Guide media successfully uploaded - `category` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `parentId` (string,null) **(required)**: - `name` (string) **(required)**: - `subtitle` (string,null) **(required)**: - `description` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `imageAspectRatio` (string) **(required)**: Values: `square`, `wide` - `guideTitle` (string,null) **(required)**: - `guideBody` (string,null) **(required)**: - `guideMediaKey` (string,null) **(required)**: - `guideMediaType` (string,null) **(required)**: Values: `image`, `video`, `null` - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid file type or file too large ### 403: Only labs can upload category guide media ### 404: Category not found ### 500: Internal server error or storage not configured ## Example ```bash curl -X POST "https://api.guidelab.co/categories/{id}/guide-media" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete category guide media `DELETE https://api.guidelab.co/categories/{id}/guide-media` Remove the decision-guide media for a product category from R2 storage and clear the guideMediaKey reference. Documentation: https://docs.guidelab.co/api-reference/categories/deleteCategoryGuideMedia ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Category ID ## Responses ### 200: Guide media successfully removed - `category` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `parentId` (string,null) **(required)**: - `name` (string) **(required)**: - `subtitle` (string,null) **(required)**: - `description` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `imageAspectRatio` (string) **(required)**: Values: `square`, `wide` - `guideTitle` (string,null) **(required)**: - `guideBody` (string,null) **(required)**: - `guideMediaKey` (string,null) **(required)**: - `guideMediaType` (string,null) **(required)**: Values: `image`, `video`, `null` - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `message` (string) **(required)**: ### 400: Category has no guide media ### 403: Only labs can delete category guide media ### 404: Category not found ### 500: Internal server error or storage not configured ## Example ```bash curl -X DELETE "https://api.guidelab.co/categories/{id}/guide-media" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List bundles `GET https://api.guidelab.co/bundles` Retrieve a paginated list of product bundles for the authenticated lab, with optional filtering by category, search term, and visibility status. Documentation: https://docs.guidelab.co/api-reference/bundles/listBundles ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (string) (in: query): - `limit` (string) (in: query): - `search` (string) (in: query): - `categoryId` (string) (in: query): - `includeInactive` (string) (in: query): - `includeHidden` (string) (in: query): - `sortBy` (string) (in: query): - `sortOrder` (string) (in: query): - `labId` (string) (in: query): - `clinicId` (string) (in: query): Lab viewers only: price the bundles for this customer, as the order will be charged. ## Responses ### 200: Paginated list of bundles with their items - `data` (array) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 403: User does not have permission to access bundles ### 404: Not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/bundles" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a bundle `POST https://api.guidelab.co/bundles` Create a new product bundle with at least 2 products. Validates that all referenced products and category belong to the lab, and checks SKU uniqueness. Documentation: https://docs.guidelab.co/api-reference/bundles/createBundle ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `sku` (string): - `description` (string): - `categoryId` (string): - `bundlePrice` (string) **(required)**: - `isActive` (boolean): (default: `true`) - `isHidden` (boolean): (default: `false`) - `sortOrder` (integer): (default: `0`) - `shareTeeth` (boolean): (default: `false`) - `shareMaterial` (boolean): (default: `false`) - `shareShade` (boolean): (default: `false`) - `quantityEnabled` (boolean): (default: `false`) - `items` (object[]) **(required)**: - `productId` (string) **(required)**: - `sortOrder` (integer): (default: `0`) ## Responses ### 201: Bundle successfully created with its items - `bundle` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `description` (string,null) **(required)**: - `bundlePrice` (string) **(required)**: - `isActive` (boolean) **(required)**: - `isHidden` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `shareTeeth` (boolean) **(required)**: - `shareMaterial` (boolean) **(required)**: - `shareShade` (boolean) **(required)**: - `quantityEnabled` (boolean) **(required)**: - `createdAt` (object): - `updatedAt` (object): - `items` (object[]) **(required)**: - `id` (string) **(required)**: - `bundleId` (string) **(required)**: - `productId` (string) **(required)**: - `sortOrder` (number) **(required)**: - `product` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `defaultPrice` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: ### 400: Invalid request body or products not found ### 403: Only labs can create bundles ### 404: Category not found ### 409: A bundle with this SKU already exists ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/bundles" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "bundlePrice": "string", "items": [ { "productId": "string", "sortOrder": 0 } ] }' ``` --- # Get a bundle `GET https://api.guidelab.co/bundles/{id}` Retrieve a single bundle by its ID, including its items with full product details and category information. Documentation: https://docs.guidelab.co/api-reference/bundles/getBundle ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Bundle ID - `clinicId` (string) (in: query): Lab viewers only: price the bundle for this customer, as the order will be charged. ## Responses ### 200: Bundle details with items and category - `bundle` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `description` (string,null) **(required)**: - `bundlePrice` (string) **(required)**: - `isActive` (boolean) **(required)**: - `isHidden` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `shareTeeth` (boolean) **(required)**: - `shareMaterial` (boolean) **(required)**: - `shareShade` (boolean) **(required)**: - `quantityEnabled` (boolean) **(required)**: - `createdAt` (object): - `updatedAt` (object): - `items` (object[]) **(required)**: - `id` (string) **(required)**: - `bundleId` (string) **(required)**: - `productId` (string) **(required)**: - `sortOrder` (number) **(required)**: - `product` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `defaultPrice` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `category` (object,null) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: ### 400: Invalid request ### 403: User does not have permission to view this bundle ### 404: Bundle not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/bundles/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Partially update a bundle `PATCH https://api.guidelab.co/bundles/{id}` Partially update a bundle's boolean flags such as isActive, isHidden, shareTeeth, shareMaterial, shareShade, or quantityEnabled. Documentation: https://docs.guidelab.co/api-reference/bundles/patchBundle ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Bundle ID ## Request Body Content-Type: `application/json` - `isActive` (boolean): - `isHidden` (boolean): - `shareTeeth` (boolean): - `shareMaterial` (boolean): - `shareShade` (boolean): - `quantityEnabled` (boolean): ## Responses ### 200: Bundle partially updated - `bundle` (object): ### 400: Invalid request ### 403: Only labs can modify bundles ### 404: Bundle not found ### 500: Internal server error ## Example ```bash curl -X PATCH "https://api.guidelab.co/bundles/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "isActive": true, "isHidden": true, "shareTeeth": true, "shareMaterial": true, "shareShade": true, "quantityEnabled": true }' ``` --- # Delete a bundle `DELETE https://api.guidelab.co/bundles/{id}` Soft-delete a bundle by setting it to inactive. The bundle record and its items are preserved for historical reference. Documentation: https://docs.guidelab.co/api-reference/bundles/deleteBundle ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Bundle ID ## Responses ### 200: Bundle deactivated successfully - `success` (boolean) **(required)**: ### 400: Invalid request ### 403: Only labs can delete bundles ### 404: Bundle not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/bundles/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a bundle `PUT https://api.guidelab.co/bundles/{id}` Update an existing bundle's properties and optionally replace its items. Validates category, products ownership, and SKU uniqueness. Documentation: https://docs.guidelab.co/api-reference/bundles/updateBundle ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Bundle ID ## Request Body Content-Type: `application/json` - `name` (string): - `sku` (string): - `description` (string): - `categoryId` (string): - `bundlePrice` (string): - `isActive` (boolean): - `isHidden` (boolean): - `sortOrder` (integer): - `shareTeeth` (boolean): - `shareMaterial` (boolean): - `shareShade` (boolean): - `quantityEnabled` (boolean): - `items` (object[]): - `productId` (string) **(required)**: - `sortOrder` (integer): (default: `0`) ## Responses ### 200: Bundle successfully updated with its items - `bundle` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `description` (string,null) **(required)**: - `bundlePrice` (string) **(required)**: - `isActive` (boolean) **(required)**: - `isHidden` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `shareTeeth` (boolean) **(required)**: - `shareMaterial` (boolean) **(required)**: - `shareShade` (boolean) **(required)**: - `quantityEnabled` (boolean) **(required)**: - `createdAt` (object): - `updatedAt` (object): - `items` (object[]) **(required)**: - `id` (string) **(required)**: - `bundleId` (string) **(required)**: - `productId` (string) **(required)**: - `sortOrder` (number) **(required)**: - `product` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `defaultPrice` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: ### 400: Invalid request body or products not found ### 403: Only labs can update bundles ### 404: Bundle or category not found ### 409: A bundle with this SKU already exists ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/bundles/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # List materials `GET https://api.guidelab.co/materials` Retrieve a paginated list of materials for the authenticated lab, with optional search and inactive filtering. Documentation: https://docs.guidelab.co/api-reference/materials/listMaterials ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` (string) (in: query): - `search` (string) (in: query): - `page` (string) (in: query): - `limit` (string) (in: query): - `labId` (string) (in: query): ## Responses ### 200: Paginated list of materials - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string,null) **(required)**: - `valuePerGram` (string,null) **(required)**: - `description` (string,null) **(required)**: - `iconKey` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 403: User does not have permission to access materials ### 404: Lab not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/materials" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a material `POST https://api.guidelab.co/materials` Create a new material in the lab's catalog. Materials carry cost information such as value per gram; markup is configured per product on the product-material association. Documentation: https://docs.guidelab.co/api-reference/materials/createMaterial ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `code` (string): - `valuePerGram` (string,null): - `description` (string): - `isActive` (boolean): (default: `true`) - `sortOrder` (integer): (default: `0`) ## Responses ### 201: Material successfully created - `material` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string,null) **(required)**: - `valuePerGram` (string,null) **(required)**: - `description` (string,null) **(required)**: - `iconKey` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 403: Only labs can create materials ### 404: Not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/materials" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "code": "string", "valuePerGram": "string", "description": "string", "isActive": true, "sortOrder": 0 }' ``` --- # Get a material `GET https://api.guidelab.co/materials/{id}` Retrieve a single material by its ID. Clinic users must have an active partnership with the owning lab. Documentation: https://docs.guidelab.co/api-reference/materials/getMaterial ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Material ID ## Responses ### 200: Material details - `material` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string,null) **(required)**: - `valuePerGram` (string,null) **(required)**: - `description` (string,null) **(required)**: - `iconKey` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request ### 403: User does not have permission to view this material ### 404: Material not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/materials/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete a material `DELETE https://api.guidelab.co/materials/{id}` Soft-delete a material by setting it to inactive. The material record is preserved for historical reference. Documentation: https://docs.guidelab.co/api-reference/materials/deleteMaterial ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Material ID ## Responses ### 200: Material deactivated successfully - `material` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string,null) **(required)**: - `valuePerGram` (string,null) **(required)**: - `description` (string,null) **(required)**: - `iconKey` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `message` (string) **(required)**: ### 400: Invalid request ### 403: Only labs can delete materials ### 404: Material not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/materials/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a material `PUT https://api.guidelab.co/materials/{id}` Update an existing material's properties including name, code, pricing, and active status. Documentation: https://docs.guidelab.co/api-reference/materials/updateMaterial ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Material ID ## Request Body Content-Type: `application/json` - `name` (string): - `code` (string): - `valuePerGram` (string,null): - `description` (string): - `isActive` (boolean): - `sortOrder` (integer): ## Responses ### 200: Material successfully updated - `material` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string,null) **(required)**: - `valuePerGram` (string,null) **(required)**: - `description` (string,null) **(required)**: - `iconKey` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 403: Only labs can update materials ### 404: Material not found ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/materials/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "code": "string", "valuePerGram": "string", "description": "string", "isActive": true, "sortOrder": 0 }' ``` --- # Get material icon `GET https://api.guidelab.co/materials/{id}/icon` Retrieve the icon image associated with a material from R2 storage. Returns the raw image binary with appropriate content-type headers. Documentation: https://docs.guidelab.co/api-reference/materials/getMaterialIcon ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Material ID ## Responses ### 200: Material icon binary data ### 404: Material or icon not found ### 500: Storage not configured ## Example ```bash curl -X GET "https://api.guidelab.co/materials/{id}/icon" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload material icon `POST https://api.guidelab.co/materials/{id}/icon` Upload or replace the icon for a material. Accepts JPEG, PNG, WebP, or GIF up to 5MB via multipart form data. Documentation: https://docs.guidelab.co/api-reference/materials/uploadMaterialIcon ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Material ID ## Responses ### 200: Icon successfully uploaded - `material` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string,null) **(required)**: - `valuePerGram` (string,null) **(required)**: - `description` (string,null) **(required)**: - `iconKey` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid file type or file too large ### 403: Only labs can upload material icons ### 404: Material not found ### 500: Internal server error or storage not configured ## Example ```bash curl -X POST "https://api.guidelab.co/materials/{id}/icon" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete material icon `DELETE https://api.guidelab.co/materials/{id}/icon` Remove the icon associated with a material from R2 storage and clear the iconKey reference. Documentation: https://docs.guidelab.co/api-reference/materials/deleteMaterialIcon ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Material ID ## Responses ### 200: Material icon successfully removed - `material` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string,null) **(required)**: - `valuePerGram` (string,null) **(required)**: - `description` (string,null) **(required)**: - `iconKey` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `message` (string) **(required)**: ### 400: Material has no icon ### 403: Only labs can delete material icons ### 404: Material not found ### 500: Internal server error or storage not configured ## Example ```bash curl -X DELETE "https://api.guidelab.co/materials/{id}/icon" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List file requirements `GET https://api.guidelab.co/file-requirements` List the lab's file requirement library entries with usage counts. Documentation: https://docs.guidelab.co/api-reference/file-requirements/listFileRequirements ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeArchived` (string) (in: query): - `search` (string) (in: query): - `page` (string) (in: query): - `limit` (string) (in: query): ## Responses ### 200: Paginated list of file requirements - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `acceptedExtensions` (string[]) **(required)**: - `slots` (object[]) **(required)**: - `id` (string) **(required)**: - `label` (string) **(required)**: - `required` (boolean) **(required)**: - `exampleImageKey` (string): - `exampleImageKey` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `archivedAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `productsUsingCount` (number): - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 403: Forbidden ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/file-requirements" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create file requirement `POST https://api.guidelab.co/file-requirements` Create a new file requirement library entry. Documentation: https://docs.guidelab.co/api-reference/file-requirements/createFileRequirement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `description` (string,null): - `acceptedExtensions` (string[]) **(required)**: - `slots` (object[]): (default: ``) - `id` (string) **(required)**: - `label` (string) **(required)**: - `required` (boolean): (default: `true`) - `exampleImageKey` (string): - `exampleImageKey` (string,null): - `sortOrder` (integer): (default: `0`) ## Responses ### 201: Created - `fileRequirement` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `acceptedExtensions` (string[]) **(required)**: - `slots` (object[]) **(required)**: - `id` (string) **(required)**: - `label` (string) **(required)**: - `required` (boolean) **(required)**: - `exampleImageKey` (string): - `exampleImageKey` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `archivedAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `productsUsingCount` (number): ### 400: Invalid request body ### 403: Forbidden ## Example ```bash curl -X POST "https://api.guidelab.co/file-requirements" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string", "acceptedExtensions": [ "string" ], "slots": [ { "id": "string", "label": "string", "required": true, "exampleImageKey": "string" } ], "exampleImageKey": "string", "sortOrder": 0 }' ``` --- # Get file requirement `GET https://api.guidelab.co/file-requirements/{id}` Get a single file requirement library entry. Documentation: https://docs.guidelab.co/api-reference/file-requirements/getFileRequirement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: OK - `fileRequirement` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `acceptedExtensions` (string[]) **(required)**: - `slots` (object[]) **(required)**: - `id` (string) **(required)**: - `label` (string) **(required)**: - `required` (boolean) **(required)**: - `exampleImageKey` (string): - `exampleImageKey` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `archivedAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `productsUsingCount` (number): ### 404: Not found ## Example ```bash curl -X GET "https://api.guidelab.co/file-requirements/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Archive file requirement `DELETE https://api.guidelab.co/file-requirements/{id}` Archive a file requirement library entry. Rejects if any products currently reference it. Documentation: https://docs.guidelab.co/api-reference/file-requirements/archiveFileRequirement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Archived - `fileRequirement` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `acceptedExtensions` (string[]) **(required)**: - `slots` (object[]) **(required)**: - `id` (string) **(required)**: - `label` (string) **(required)**: - `required` (boolean) **(required)**: - `exampleImageKey` (string): - `exampleImageKey` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `archivedAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `productsUsingCount` (number): ### 404: Not found ### 409: In use by one or more products ## Example ```bash curl -X DELETE "https://api.guidelab.co/file-requirements/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update file requirement `PUT https://api.guidelab.co/file-requirements/{id}` Update a file requirement library entry. Documentation: https://docs.guidelab.co/api-reference/file-requirements/updateFileRequirement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `name` (string): - `description` (string,null): - `acceptedExtensions` (string[]): - `slots` (object[]): - `id` (string) **(required)**: - `label` (string) **(required)**: - `required` (boolean): (default: `true`) - `exampleImageKey` (string): - `exampleImageKey` (string,null): - `sortOrder` (integer): ## Responses ### 200: OK - `fileRequirement` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `acceptedExtensions` (string[]) **(required)**: - `slots` (object[]) **(required)**: - `id` (string) **(required)**: - `label` (string) **(required)**: - `required` (boolean) **(required)**: - `exampleImageKey` (string): - `exampleImageKey` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `archivedAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `productsUsingCount` (number): ### 404: Not found ### 409: A removed slot still has uploaded files ## Example ```bash curl -X PUT "https://api.guidelab.co/file-requirements/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string", "acceptedExtensions": [ "string" ], "slots": [ { "id": "string", "label": "string", "required": true, "exampleImageKey": "string" } ], "exampleImageKey": "string", "sortOrder": 0 }' ``` --- # Restore file requirement `POST https://api.guidelab.co/file-requirements/{id}/restore` Restore an archived file requirement so it can be linked to products again. Documentation: https://docs.guidelab.co/api-reference/file-requirements/restoreFileRequirement ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Restored - `fileRequirement` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `acceptedExtensions` (string[]) **(required)**: - `slots` (object[]) **(required)**: - `id` (string) **(required)**: - `label` (string) **(required)**: - `required` (boolean) **(required)**: - `exampleImageKey` (string): - `exampleImageKey` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `archivedAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `productsUsingCount` (number): ### 404: Not found ## Example ```bash curl -X POST "https://api.guidelab.co/file-requirements/{id}/restore" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload file requirement example image `POST https://api.guidelab.co/file-requirements/example-image` Upload a reference image for a file requirement or one of its upload slots. Returns the managed asset id to store on the requirement; the image is only retained once a save references it. Documentation: https://docs.guidelab.co/api-reference/file-requirements/uploadFileRequirementExampleImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Uploaded - `imageKey` (string) **(required)**: ### 400: Missing file, invalid type, or file too large ### 403: Only labs can upload file requirement examples ### 500: Storage not configured ## Example ```bash curl -X POST "https://api.guidelab.co/file-requirements/example-image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get file requirement example image `GET https://api.guidelab.co/file-requirements/{id}/example-image` Stream a file requirement's reference image. The key must be one this requirement actually references; the owning lab and its partnered clinics may read it. Documentation: https://docs.guidelab.co/api-reference/file-requirements/getFileRequirementExampleImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `key` (string) (in: query): ## Responses ### 200: Example image binary data ### 400: Missing image key ### 404: Requirement or image not found ### 500: Storage not configured ## Example ```bash curl -X GET "https://api.guidelab.co/file-requirements/{id}/example-image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List shade systems `GET https://api.guidelab.co/shade-systems` Retrieve shade systems and their stable values for the requested lab. Documentation: https://docs.guidelab.co/api-reference/shade-systems/listShadeSystems ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` (string) (in: query): - `defaultOnly` (string) (in: query): - `labId` (string) (in: query): ## Responses ### 200: List of shade systems, or with defaultOnly the default system (else the first active one) ### 400: Invalid query parameters ### 403: User does not have permission ### 404: Lab not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/shade-systems" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a shade system `POST https://api.guidelab.co/shade-systems` Create a shade system and its stable value rows. Documentation: https://docs.guidelab.co/api-reference/shade-systems/createShadeSystem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `description` (string): - `isDefault` (boolean): (default: `false`) - `isActive` (boolean): (default: `true`) - `sortOrder` (integer): (default: `0`) - `values` (object[]): (default: ``) - `id` (string): - `code` (string) **(required)**: - `label` (string): - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 201: Shade system created - `system` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `values` (object[]) **(required)**: - `id` (string) **(required)**: - `code` (string) **(required)**: - `label` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `images` (object) **(required)**: - `occlusal` (string,null) **(required)**: - `middle` (string,null) **(required)**: - `gingival` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 403: Only labs can create shade systems ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/shade-systems" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string", "isDefault": true, "isActive": true, "sortOrder": 0, "values": [ { "id": "string", "code": "string", "label": "string", "sortOrder": 0, "isActive": true } ] }' ``` --- # Get a shade system `GET https://api.guidelab.co/shade-systems/{id}` Retrieve one shade system. Clinic users require a partnership with its lab. Documentation: https://docs.guidelab.co/api-reference/shade-systems/getShadeSystem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Shade system - `system` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `values` (object[]) **(required)**: - `id` (string) **(required)**: - `code` (string) **(required)**: - `label` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `images` (object) **(required)**: - `occlusal` (string,null) **(required)**: - `middle` (string,null) **(required)**: - `gingival` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 403: Forbidden ### 404: Shade system not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/shade-systems/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Patch a shade system `PATCH https://api.guidelab.co/shade-systems/{id}` Perform a shade-system action. Documentation: https://docs.guidelab.co/api-reference/shade-systems/patchShadeSystem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `action` (string): ## Responses ### 200: Action completed - `system` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `values` (object[]) **(required)**: - `id` (string) **(required)**: - `code` (string) **(required)**: - `label` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `images` (object) **(required)**: - `occlusal` (string,null) **(required)**: - `middle` (string,null) **(required)**: - `gingival` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid action ### 403: Only labs can update shade systems ### 404: Shade system not found ### 500: Internal server error ## Example ```bash curl -X PATCH "https://api.guidelab.co/shade-systems/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "action": "string" }' ``` --- # Delete a shade system `DELETE https://api.guidelab.co/shade-systems/{id}` Soft-delete a non-default shade system. Documentation: https://docs.guidelab.co/api-reference/shade-systems/deleteShadeSystem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Shade system deactivated - `system` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `values` (object[]) **(required)**: - `id` (string) **(required)**: - `code` (string) **(required)**: - `label` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `images` (object) **(required)**: - `occlusal` (string,null) **(required)**: - `middle` (string,null) **(required)**: - `gingival` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `message` (string) **(required)**: ### 400: Cannot delete the default shade system ### 403: Only labs can delete shade systems ### 404: Shade system not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/shade-systems/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a shade system `PUT https://api.guidelab.co/shade-systems/{id}` Update a shade system and reconcile stable values by ID. Renames preserve image assets. Documentation: https://docs.guidelab.co/api-reference/shade-systems/updateShadeSystem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `name` (string): - `description` (string): - `isDefault` (boolean): - `isActive` (boolean): - `sortOrder` (integer): - `values` (object[]): - `id` (string): - `code` (string) **(required)**: - `label` (string): - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 200: Shade system updated - `system` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `values` (object[]) **(required)**: - `id` (string) **(required)**: - `code` (string) **(required)**: - `label` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `images` (object) **(required)**: - `occlusal` (string,null) **(required)**: - `middle` (string,null) **(required)**: - `gingival` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body or value identity ### 403: Only labs can update shade systems ### 404: Shade system not found ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/shade-systems/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string", "isDefault": true, "isActive": true, "sortOrder": 0, "values": [ { "id": "string", "code": "string", "label": "string", "sortOrder": 0, "isActive": true } ] }' ``` --- # Get shade value image `GET https://api.guidelab.co/shade-systems/{id}/values/{valueId}/image` Stream a stable shade value's position image. Documentation: https://docs.guidelab.co/api-reference/shade-systems/getShadeValueImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `valueId` (string) **(required)** (in: path): - `position` (string) **(required)** (in: query): Values: `occlusal`, `middle`, `gingival` ## Responses ### 200: Image binary data ### 404: Image not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/shade-systems/{id}/values/{valueId}/image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload shade value image `POST https://api.guidelab.co/shade-systems/{id}/values/{valueId}/image` Upload or replace one position image for a stable shade value (maximum 5MB). Documentation: https://docs.guidelab.co/api-reference/shade-systems/uploadShadeValueImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `valueId` (string) **(required)** (in: path): - `position` (string) **(required)** (in: query): Values: `occlusal`, `middle`, `gingival` ## Responses ### 200: Image uploaded - `system` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `values` (object[]) **(required)**: - `id` (string) **(required)**: - `code` (string) **(required)**: - `label` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `images` (object) **(required)**: - `occlusal` (string,null) **(required)**: - `middle` (string,null) **(required)**: - `gingival` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `url` (string,null) **(required)**: ### 400: Invalid file or position ### 403: Only labs can upload shade value images ### 404: Shade system or value not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/shade-systems/{id}/values/{valueId}/image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete shade value image `DELETE https://api.guidelab.co/shade-systems/{id}/values/{valueId}/image` Clear and enqueue deletion of one shade-value image. Documentation: https://docs.guidelab.co/api-reference/shade-systems/deleteShadeValueImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `valueId` (string) **(required)** (in: path): - `position` (string) **(required)** (in: query): Values: `occlusal`, `middle`, `gingival` ## Responses ### 200: Image removed - `system` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `values` (object[]) **(required)**: - `id` (string) **(required)**: - `code` (string) **(required)**: - `label` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `images` (object) **(required)**: - `occlusal` (string,null) **(required)**: - `middle` (string,null) **(required)**: - `gingival` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: No image for this value/position ### 403: Only labs can delete shade value images ### 404: Shade value not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/shade-systems/{id}/values/{valueId}/image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List implant systems `GET https://api.guidelab.co/implant-systems` Retrieve all persisted implant systems for the authenticated lab, including their inline platforms list. Organization defaults are initialized during creation or by the explicit settings-defaults command. Documentation: https://docs.guidelab.co/api-reference/implant-systems/listImplantSystems ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` (string) (in: query): - `labId` (string) (in: query): ## Responses ### 200: List of implant systems - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `manufacturer` (string,null) **(required)**: - `description` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `platforms` (object[]) **(required)**: - `code` (string) **(required)**: - `label` (string) **(required)**: - `diameter` (string): - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid query parameters ### 403: User does not have permission ### 404: Lab not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/implant-systems" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create an implant system `POST https://api.guidelab.co/implant-systems` Create a new implant system with an inline list of platforms (connections + diameters). Documentation: https://docs.guidelab.co/api-reference/implant-systems/createImplantSystem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `manufacturer` (string): - `description` (string): - `isActive` (boolean): (default: `true`) - `sortOrder` (integer): (default: `0`) - `platforms` (object[]): (default: ``) - `code` (string) **(required)**: - `label` (string) **(required)**: - `diameter` (string): - `isActive` (boolean): (default: `true`) ## Responses ### 201: Implant system created - `system` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `manufacturer` (string,null) **(required)**: - `description` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `platforms` (object[]) **(required)**: - `code` (string) **(required)**: - `label` (string) **(required)**: - `diameter` (string): - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 403: Only labs can create implant systems ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/implant-systems" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "manufacturer": "string", "description": "string", "isActive": true, "sortOrder": 0, "platforms": [ { "code": "string", "label": "string", "diameter": "string", "isActive": true } ] }' ``` --- # Load the default implant systems `POST https://api.guidelab.co/implant-systems/seed-defaults` Adds every implant system from the built-in manufacturer catalog that the lab does not already have, matched by name. Existing systems are never modified, so lab edits and previously deactivated systems are preserved. Idempotent: running it again adds nothing. Documentation: https://docs.guidelab.co/api-reference/implant-systems/seedImplantSystems ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Catalog already loaded; nothing was added - `data` (object) **(required)**: - `alreadySeeded` (boolean) **(required)**: ### 201: Missing catalog implant systems added - `data` (object) **(required)**: - `seeded` (number) **(required)**: ### 401: Unauthorized ### 403: Only labs can seed implant systems ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/implant-systems/seed-defaults" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get an implant system `GET https://api.guidelab.co/implant-systems/{id}` Retrieve a single implant system by its ID. Clinic users must have an active partnership with the owning lab. Documentation: https://docs.guidelab.co/api-reference/implant-systems/getImplantSystem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Implant system ID ## Responses ### 200: Implant system - `system` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `manufacturer` (string,null) **(required)**: - `description` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `platforms` (object[]) **(required)**: - `code` (string) **(required)**: - `label` (string) **(required)**: - `diameter` (string): - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 403: Forbidden ### 404: Implant system not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/implant-systems/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete an implant system `DELETE https://api.guidelab.co/implant-systems/{id}` Soft-delete an implant system by setting it inactive. Documentation: https://docs.guidelab.co/api-reference/implant-systems/deleteImplantSystem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Implant system deactivated - `system` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `manufacturer` (string,null) **(required)**: - `description` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `platforms` (object[]) **(required)**: - `code` (string) **(required)**: - `label` (string) **(required)**: - `diameter` (string): - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `message` (string) **(required)**: ### 403: Only labs can delete implant systems ### 404: Implant system not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/implant-systems/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update an implant system `PUT https://api.guidelab.co/implant-systems/{id}` Update an existing implant system's properties, including the full inline platforms array. Documentation: https://docs.guidelab.co/api-reference/implant-systems/updateImplantSystem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `name` (string): - `manufacturer` (string): - `description` (string): - `isActive` (boolean): - `sortOrder` (integer): - `platforms` (object[]): - `code` (string) **(required)**: - `label` (string) **(required)**: - `diameter` (string): - `isActive` (boolean): (default: `true`) ## Responses ### 200: Implant system updated - `system` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `manufacturer` (string,null) **(required)**: - `description` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `platforms` (object[]) **(required)**: - `code` (string) **(required)**: - `label` (string) **(required)**: - `diameter` (string): - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 403: Only labs can update implant systems ### 404: Implant system not found ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/implant-systems/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "manufacturer": "string", "description": "string", "isActive": true, "sortOrder": 0, "platforms": [ { "code": "string", "label": "string", "diameter": "string", "isActive": true } ] }' ``` --- # List components `GET https://api.guidelab.co/components` Retrieve all lab components (e.g. implant components) ordered by sort position, optionally including inactive ones. Documentation: https://docs.guidelab.co/api-reference/components/listComponents ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` (string) (in: query): ## Responses ### 200: List of lab components - `components` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `truncated` (boolean) **(required)**: True when the lab holds more components than one response returns. The list is capped, not refused. ### 400: Invalid query parameters ### 403: Only labs can manage components ### 404: Not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/components" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a component `POST https://api.guidelab.co/components` Create a new lab component. If sortOrder is not specified, it is automatically set to the next available position. Documentation: https://docs.guidelab.co/api-reference/components/createComponent ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `sortOrder` (integer): ## Responses ### 201: Component successfully created - `component` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 403: Only labs can manage components ### 404: Lab not found ### 409: Component row limit reached ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/components" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "sortOrder": 0 }' ``` --- # Reorder components `POST https://api.guidelab.co/components/reorder` Bulk reorder lab components by providing an ordered array of component IDs. Sort positions are assigned sequentially starting from 0. Documentation: https://docs.guidelab.co/api-reference/components/reorderComponents ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `componentIds` (string[]) **(required)**: ## Responses ### 200: Components successfully reordered - `success` (boolean) **(required)**: ### 400: Invalid request body ### 403: Only labs can manage components ### 404: One or more components not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/components/reorder" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "componentIds": [ "string" ] }' ``` --- # Get component settings `GET https://api.guidelab.co/components/settings` Retrieve the lab's component display settings, such as whether components are shown in the order page. Documentation: https://docs.guidelab.co/api-reference/components/getComponentSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Component display settings - `settings` (object) **(required)**: - `id` (string,null) **(required)**: - `labId` (string) **(required)**: - `showInOrderPage` (boolean) **(required)**: - `createdAt` (string,null) **(required)**: - `updatedAt` (string,null) **(required)**: ### 400: Invalid request ### 403: Only labs can manage components ### 404: Not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/components/settings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update component settings `PUT https://api.guidelab.co/components/settings` Update the lab's component display settings. Creates the settings record if it does not yet exist. Documentation: https://docs.guidelab.co/api-reference/components/updateComponentSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `showInOrderPage` (boolean) **(required)**: ## Responses ### 200: Component settings successfully updated - `settings` (object) **(required)**: - `id` (string,null) **(required)**: - `labId` (string) **(required)**: - `showInOrderPage` (boolean) **(required)**: - `createdAt` (string,null) **(required)**: - `updatedAt` (string,null) **(required)**: ### 400: Invalid request body ### 403: Only labs can manage components ### 404: Not found ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/components/settings" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "showInOrderPage": true }' ``` --- # Delete a component `DELETE https://api.guidelab.co/components/{id}` Soft-delete a lab component by setting it to inactive. The component record is preserved for historical reference. Documentation: https://docs.guidelab.co/api-reference/components/deleteComponent ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Component ID ## Responses ### 200: Component deactivated successfully - `component` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request ### 403: Only labs can manage components ### 404: Component not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/components/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a component `PUT https://api.guidelab.co/components/{id}` Update an existing lab component's name or active status. Documentation: https://docs.guidelab.co/api-reference/components/updateComponent ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Component ID ## Request Body Content-Type: `application/json` - `name` (string): - `isActive` (boolean): ## Responses ### 200: Component successfully updated - `component` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 403: Only labs can manage components ### 404: Component not found ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/components/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "isActive": true }' ``` --- # List treatment phases `GET https://api.guidelab.co/treatment-phases` Retrieve all treatment phases for the authenticated lab, including their ordered task list and task counts. Documentation: https://docs.guidelab.co/api-reference/treatment-phases/listTreatmentPhases ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of treatment phases with their tasks - `phases` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `defaultOffsetDays` (number) **(required)**: - `isActive` (boolean) **(required)**: - `color` (string,null): - `startPolicy` (string) **(required)**: - `leadTimeDays` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `taskCount` (number): - `tasks` (object[]): - `id` (string) **(required)**: - `taskId` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `clinicVisible` (boolean) **(required)**: - `clinicTitle` (string,null) **(required)**: - `task` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `color` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `completionTrigger` (string) **(required)**: ### 400: Invalid request ### 403: Only labs can access treatment phases ### 404: Not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/treatment-phases" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a treatment phase `POST https://api.guidelab.co/treatment-phases` Create a new treatment phase with an optional ordered task list. The phase sort order is set to the next available position. Documentation: https://docs.guidelab.co/api-reference/treatment-phases/createTreatmentPhase ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `description` (string,null): - `defaultOffsetDays` (integer): - `color` (string,null): - `startPolicy` (string): Values: `ask`, `always`, `never` - `leadTimeDays` (integer): - `tasks` (object[]): - `id` (string): - `taskId` (string) **(required)**: - `clinicVisible` (boolean): - `clinicTitle` (string,null): - `isActive` (boolean): ## Responses ### 201: Treatment phase successfully created with its tasks - `phase` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `defaultOffsetDays` (number) **(required)**: - `isActive` (boolean) **(required)**: - `color` (string,null): - `startPolicy` (string) **(required)**: - `leadTimeDays` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `taskCount` (number): - `tasks` (object[]): - `id` (string) **(required)**: - `taskId` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `clinicVisible` (boolean) **(required)**: - `clinicTitle` (string,null) **(required)**: - `task` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `color` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `completionTrigger` (string) **(required)**: ### 400: Invalid request body or task references unknown task ### 403: Only labs can create treatment phases ### 404: Not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/treatment-phases" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string" }' ``` --- # Reorder treatment phases `POST https://api.guidelab.co/treatment-phases/reorder` Bulk reorder treatment phases by providing an ordered array of phase IDs. Sort positions are assigned sequentially starting from 0. Documentation: https://docs.guidelab.co/api-reference/treatment-phases/reorderTreatmentPhases ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `phaseIds` (string[]) **(required)**: ## Responses ### 200: Treatment phases successfully reordered - `success` (boolean) **(required)**: ### 400: Invalid phaseIds array ### 403: Only labs can reorder treatment phases ### 404: One or more phases not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/treatment-phases/reorder" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "phaseIds": [ "string" ] }' ``` --- # Get a treatment phase `GET https://api.guidelab.co/treatment-phases/{id}` Retrieve a single treatment phase by its ID, including its ordered task list. Documentation: https://docs.guidelab.co/api-reference/treatment-phases/getTreatmentPhase ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Treatment phase ID ## Responses ### 200: Treatment phase details with tasks - `phase` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `defaultOffsetDays` (number) **(required)**: - `isActive` (boolean) **(required)**: - `color` (string,null): - `startPolicy` (string) **(required)**: - `leadTimeDays` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `taskCount` (number): - `tasks` (object[]): - `id` (string) **(required)**: - `taskId` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `clinicVisible` (boolean) **(required)**: - `clinicTitle` (string,null) **(required)**: - `task` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `color` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `completionTrigger` (string) **(required)**: ### 400: Invalid request ### 403: Only labs can access treatment phases ### 404: Treatment phase not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/treatment-phases/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete a treatment phase `DELETE https://api.guidelab.co/treatment-phases/{id}` Permanently delete a treatment phase and its task list. Fails if the phase is referenced by any products or order phases. Documentation: https://docs.guidelab.co/api-reference/treatment-phases/deleteTreatmentPhase ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Treatment phase ID ## Responses ### 200: Treatment phase successfully deleted - `success` (boolean) **(required)**: ### 400: Invalid request ### 403: Only labs can delete treatment phases ### 404: Treatment phase not found ### 409: Phase is referenced by products or order phases ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/treatment-phases/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a treatment phase `PUT https://api.guidelab.co/treatment-phases/{id}` Update an existing treatment phase. If `tasks` is provided, the template task list is replaced; existing orders retain their immutable task snapshots. Documentation: https://docs.guidelab.co/api-reference/treatment-phases/updateTreatmentPhase ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Treatment phase ID ## Request Body Content-Type: `application/json` - `name` (string): - `description` (string,null): - `defaultOffsetDays` (integer): - `isActive` (boolean): - `color` (string,null): - `startPolicy` (string): Values: `ask`, `always`, `never` - `leadTimeDays` (integer): - `tasks` (object[]): - `id` (string): - `taskId` (string) **(required)**: - `clinicVisible` (boolean): - `clinicTitle` (string,null): - `isActive` (boolean): ## Responses ### 200: Treatment phase successfully updated with tasks - `phase` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `defaultOffsetDays` (number) **(required)**: - `isActive` (boolean) **(required)**: - `color` (string,null): - `startPolicy` (string) **(required)**: - `leadTimeDays` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `taskCount` (number): - `tasks` (object[]): - `id` (string) **(required)**: - `taskId` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `clinicVisible` (boolean) **(required)**: - `clinicTitle` (string,null) **(required)**: - `task` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `color` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `completionTrigger` (string) **(required)**: ### 400: Invalid request body ### 403: Only labs can update treatment phases ### 404: Treatment phase not found ### 409: The requested lifecycle conflicts with task readiness, default status, or product references ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/treatment-phases/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Reorder tasks within a treatment phase `POST https://api.guidelab.co/treatment-phases/{id}/tasks/reorder` Bulk reorder the task list within a treatment phase by providing an ordered array of phase-task row IDs. Documentation: https://docs.guidelab.co/api-reference/treatment-phases/reorderPhaseTasks ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Treatment phase ID ## Request Body Content-Type: `application/json` - `phaseTaskIds` (string[]) **(required)**: ## Responses ### 200: Phase tasks successfully reordered - `success` (boolean) **(required)**: ### 400: Invalid phaseTaskIds array ### 403: Only labs can reorder phase tasks ### 404: Treatment phase or rows not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/treatment-phases/{id}/tasks/reorder" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "phaseTaskIds": [ "string" ] }' ``` --- # List quality standards `GET https://api.guidelab.co/standards` Retrieve all quality standards for the authenticated lab, optionally including inactive ones. Documentation: https://docs.guidelab.co/api-reference/standards/listStandards ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` (string) (in: query): - `labId` (string) (in: query): ## Responses ### 200: List of quality standards - `standards` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string) **(required)**: - `description` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid query parameters ### 403: User does not have permission to access standards ### 404: Lab not found ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/standards" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a quality standard `POST https://api.guidelab.co/standards` Create a new quality standard with a unique code (bronze, silver, gold, platinum, na) for the authenticated lab. Documentation: https://docs.guidelab.co/api-reference/standards/createStandard ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `code` (string) **(required)**: Values: `bronze`, `silver`, `gold`, `platinum`, `na` - `description` (string): - `sortOrder` (integer): (default: `0`) - `isActive` (boolean): (default: `true`) ## Responses ### 201: Quality standard successfully created - `standard` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string) **(required)**: - `description` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 403: Only labs can create quality standards ### 409: A standard with this code already exists ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/standards" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "code": "bronze", "description": "string", "sortOrder": 0, "isActive": true }' ``` --- # Toggle quality standard active status `PATCH https://api.guidelab.co/standards` Toggle the active/inactive status of a quality standard identified by the id query parameter. Documentation: https://docs.guidelab.co/api-reference/standards/toggleStandard ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: query): ## Responses ### 200: Quality standard active status toggled - `standard` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string) **(required)**: - `description` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Missing standard ID ### 403: Only labs can toggle quality standards ### 404: Standard not found ### 500: Internal server error ## Example ```bash curl -X PATCH "https://api.guidelab.co/standards" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a quality standard `PUT https://api.guidelab.co/standards` Update an existing quality standard identified by the id query parameter. Validates code uniqueness if the code is being changed. Documentation: https://docs.guidelab.co/api-reference/standards/updateStandard ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: query): ## Request Body Content-Type: `application/json` - `name` (string): - `code` (string): Values: `bronze`, `silver`, `gold`, `platinum`, `na` - `description` (string): - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 200: Quality standard successfully updated - `standard` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string) **(required)**: - `description` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body or missing standard ID ### 403: Only labs can update quality standards ### 404: Standard not found ### 409: A standard with this code already exists ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/standards" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "code": "bronze", "description": "string", "sortOrder": 0, "isActive": true }' ``` --- # List stable price books and their versions `GET https://api.guidelab.co/price-lists` Documentation: https://docs.guidelab.co/api-reference/price-lists/listPriceLists ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Price books and immutable publication history - `priceLists` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] - `archivedAt` (string,null) **(required)**: [date-time] - `archivedBy` (string,null) **(required)**: - `versions` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `priceListId` (string) **(required)**: - `currency` (string) **(required)**: - `publicationNumber` (integer,null) **(required)**: - `defaultDiscountPercent` (string,null) **(required)**: - `revision` (integer) **(required)**: - `effectiveFrom` (string,null) **(required)**: [date-time] - `effectiveUntil` (string,null) **(required)**: [date-time] - `createdBy` (string) **(required)**: - `publishedAt` (string,null) **(required)**: [date-time] - `publishedBy` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: [date-time] - `cancelledBy` (string,null) **(required)**: - `endedEarlyAt` (string,null) **(required)**: [date-time] - `endedEarlyBy` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] - `hiddenProductIds` (string[]) **(required)**: ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/price-lists" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a stable price book `POST https://api.guidelab.co/price-lists` Documentation: https://docs.guidelab.co/api-reference/price-lists/createPriceList ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `description` (string,null): - `isDefault` (boolean): (default: `false`) ## Responses ### 201: Price book created - `priceList` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] - `archivedAt` (string,null) **(required)**: [date-time] - `archivedBy` (string,null) **(required)**: ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/price-lists" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string", "isDefault": true }' ``` --- # Get one price book with its versions `GET https://api.guidelab.co/price-lists/{priceListId}` Documentation: https://docs.guidelab.co/api-reference/price-lists/getPriceList ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): ## Responses ### 200: Price book and its publication history - `priceList` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] - `archivedAt` (string,null) **(required)**: [date-time] - `archivedBy` (string,null) **(required)**: - `versions` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `priceListId` (string) **(required)**: - `currency` (string) **(required)**: - `publicationNumber` (integer,null) **(required)**: - `defaultDiscountPercent` (string,null) **(required)**: - `revision` (integer) **(required)**: - `effectiveFrom` (string,null) **(required)**: [date-time] - `effectiveUntil` (string,null) **(required)**: [date-time] - `createdBy` (string) **(required)**: - `publishedAt` (string,null) **(required)**: [date-time] - `publishedBy` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: [date-time] - `cancelledBy` (string,null) **(required)**: - `endedEarlyAt` (string,null) **(required)**: [date-time] - `endedEarlyBy` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] - `hiddenProductIds` (string[]) **(required)**: ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/price-lists/{priceListId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update stable price-book metadata `PATCH https://api.guidelab.co/price-lists/{priceListId}` Documentation: https://docs.guidelab.co/api-reference/price-lists/updatePriceList ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `name` (string): - `description` (string,null): - `isDefault` (boolean): ## Responses ### 200: Price book updated - `priceList` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] - `archivedAt` (string,null) **(required)**: [date-time] - `archivedBy` (string,null) **(required)**: ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X PATCH "https://api.guidelab.co/price-lists/{priceListId}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string", "isDefault": true }' ``` --- # Archive or restore a price book `POST https://api.guidelab.co/price-lists/{priceListId}/archive` `archived: true` archives a non-default, unassigned list; `archived: false` restores it (409 price_list_name_taken when its name was reused meanwhile). Documentation: https://docs.guidelab.co/api-reference/price-lists/archivePriceList ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `archived` (boolean) **(required)**: ## Responses ### 200: Price book archived or restored - `priceList` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] - `archivedAt` (string,null) **(required)**: [date-time] - `archivedBy` (string,null) **(required)**: ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/price-lists/{priceListId}/archive" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "archived": true }' ``` --- # Copy a price book's prices into a new book, as a draft to publish `POST https://api.guidelab.co/price-lists/{priceListId}/duplicate` Documentation: https://docs.guidelab.co/api-reference/price-lists/duplicatePriceList ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `description` (string,null): ## Responses ### 201: Price book created. `version` is null when the source had no prices; `currencyMismatch` means they were in another currency and were not copied. - `priceList` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `isDefault` (boolean) **(required)**: - `createdBy` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] - `archivedAt` (string,null) **(required)**: [date-time] - `archivedBy` (string,null) **(required)**: - `version` (object,null) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `priceListId` (string) **(required)**: - `currency` (string) **(required)**: - `publicationNumber` (integer,null) **(required)**: - `defaultDiscountPercent` (string,null) **(required)**: - `revision` (integer) **(required)**: - `effectiveFrom` (string,null) **(required)**: [date-time] - `effectiveUntil` (string,null) **(required)**: [date-time] - `createdBy` (string) **(required)**: - `publishedAt` (string,null) **(required)**: [date-time] - `publishedBy` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: [date-time] - `cancelledBy` (string,null) **(required)**: - `endedEarlyAt` (string,null) **(required)**: [date-time] - `endedEarlyBy` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] - `currencyMismatch` (boolean) **(required)**: ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/price-lists/{priceListId}/duplicate" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string" }' ``` --- # Replace the products hidden from this price book's customers `PUT https://api.guidelab.co/price-lists/{priceListId}/hidden-products` Documentation: https://docs.guidelab.co/api-reference/price-lists/updatePriceListHiddenProducts ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `productIds` (string[]) **(required)**: ## Responses ### 200: Hidden product set replaced - `productIds` (string[]) **(required)**: ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/price-lists/{priceListId}/hidden-products" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "productIds": [ "string" ] }' ``` --- # Create the one editable draft for a price book `POST https://api.guidelab.co/price-lists/{priceListId}/versions` Documentation: https://docs.guidelab.co/api-reference/price-lists/createPriceListVersion ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `cloneFromVersionId` (string): ## Responses ### 201: Draft created - `version` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `priceListId` (string) **(required)**: - `currency` (string) **(required)**: - `publicationNumber` (integer,null) **(required)**: - `defaultDiscountPercent` (string,null) **(required)**: - `revision` (integer) **(required)**: - `effectiveFrom` (string,null) **(required)**: [date-time] - `effectiveUntil` (string,null) **(required)**: [date-time] - `createdBy` (string) **(required)**: - `publishedAt` (string,null) **(required)**: [date-time] - `publishedBy` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: [date-time] - `cancelledBy` (string,null) **(required)**: - `endedEarlyAt` (string,null) **(required)**: [date-time] - `endedEarlyBy` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/price-lists/{priceListId}/versions" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "cloneFromVersionId": "string" }' ``` --- # Get a version with its product and bundle rules `GET https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}` Documentation: https://docs.guidelab.co/api-reference/price-lists/getPriceListVersion ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): - `versionId` (string) **(required)** (in: path): ## Responses ### 200: Version detail - `version` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `priceListId` (string) **(required)**: - `currency` (string) **(required)**: - `publicationNumber` (integer,null) **(required)**: - `defaultDiscountPercent` (string,null) **(required)**: - `revision` (integer) **(required)**: - `effectiveFrom` (string,null) **(required)**: [date-time] - `effectiveUntil` (string,null) **(required)**: [date-time] - `createdBy` (string) **(required)**: - `publishedAt` (string,null) **(required)**: [date-time] - `publishedBy` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: [date-time] - `cancelledBy` (string,null) **(required)**: - `endedEarlyAt` (string,null) **(required)**: [date-time] - `endedEarlyBy` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] - `rules` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `priceListVersionId` (string) **(required)**: - `targetKind` (string) **(required)**: Values: `product`, `bundle`, `shipping_type` - `productId` (string,null) **(required)**: - `bundleId` (string,null) **(required)**: - `shippingTypeId` (string,null): - `fixedPrice` (string,null) **(required)**: - `discountPercent` (string,null) **(required)**: - `overrides` (object,null): - `bandTable` (object): - `perArch` (boolean) **(required)**: - `bands` (object[]) **(required)**: - `minCount` (integer) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `materialBands` (object): - `catalog` (object): - `perArch` (boolean) **(required)**: - `bands` (object[]) **(required)**: - `minCount` (integer) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `materialBands` (object): - `surcharges` (object): - `implant` (string): - `pontic` (string): - `materialMarkups` (object): - `optionPrices` (object): - `switchPrices` (object): - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] - `productRules` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `priceListVersionId` (string) **(required)**: - `productId` (string) **(required)**: - `fixedPrice` (string,null) **(required)**: - `discountPercent` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] - `bundleRules` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `priceListVersionId` (string) **(required)**: - `bundleId` (string) **(required)**: - `fixedPrice` (string,null) **(required)**: - `discountPercent` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update draft defaults with optimistic concurrency `PATCH https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}` Documentation: https://docs.guidelab.co/api-reference/price-lists/updatePriceListVersion ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): - `versionId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `expectedRevision` (integer) **(required)**: - `defaultDiscountPercent` (string,null) **(required)**: ## Responses ### 200: Draft updated - `version` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `priceListId` (string) **(required)**: - `currency` (string) **(required)**: - `publicationNumber` (integer,null) **(required)**: - `defaultDiscountPercent` (string,null) **(required)**: - `revision` (integer) **(required)**: - `effectiveFrom` (string,null) **(required)**: [date-time] - `effectiveUntil` (string,null) **(required)**: [date-time] - `createdBy` (string) **(required)**: - `publishedAt` (string,null) **(required)**: [date-time] - `publishedBy` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: [date-time] - `cancelledBy` (string,null) **(required)**: - `endedEarlyAt` (string,null) **(required)**: [date-time] - `endedEarlyBy` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X PATCH "https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "expectedRevision": 0, "defaultDiscountPercent": "string" }' ``` --- # Delete a draft product rule `DELETE https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/products/{productId}` Documentation: https://docs.guidelab.co/api-reference/price-lists/deletePriceListProductRule ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): - `versionId` (string) **(required)** (in: path): - `productId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `expectedRevision` (integer) **(required)**: ## Responses ### 200: Rule deleted - `deleted` (boolean) **(required)**: - `revision` (integer) **(required)**: ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/products/{productId}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "expectedRevision": 0 }' ``` --- # Set a draft product rule `PUT https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/products/{productId}` Documentation: https://docs.guidelab.co/api-reference/price-lists/upsertPriceListProductRule ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): - `versionId` (string) **(required)** (in: path): - `productId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `expectedRevision` (integer) **(required)**: - `rule` (object) **(required)**: - `overrides` (object,null): - `bandTable` (object): - `perArch` (boolean) **(required)**: - `bands` (object[]) **(required)**: - `minCount` (integer) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `materialBands` (object): - `catalog` (object): - `perArch` (boolean) **(required)**: - `bands` (object[]) **(required)**: - `minCount` (integer) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `materialBands` (object): - `surcharges` (object): - `implant` (string): - `pontic` (string): - `materialMarkups` (object): - `optionPrices` (object): - `switchPrices` (object): ## Responses ### 200: Rule saved - `rule` (object,null) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `priceListVersionId` (string) **(required)**: - `targetKind` (string) **(required)**: Values: `product`, `bundle`, `shipping_type` - `productId` (string,null) **(required)**: - `bundleId` (string,null) **(required)**: - `shippingTypeId` (string,null): - `fixedPrice` (string,null) **(required)**: - `discountPercent` (string,null) **(required)**: - `overrides` (object,null): - `bandTable` (object): - `perArch` (boolean) **(required)**: - `bands` (object[]) **(required)**: - `minCount` (integer) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `materialBands` (object): - `catalog` (object): - `perArch` (boolean) **(required)**: - `bands` (object[]) **(required)**: - `minCount` (integer) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `materialBands` (object): - `surcharges` (object): - `implant` (string): - `pontic` (string): - `materialMarkups` (object): - `optionPrices` (object): - `switchPrices` (object): - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] - `revision` (integer) **(required)**: ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/products/{productId}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "expectedRevision": 0, "rule": "string", "overrides": { "bandTable": { "perArch": true, "bands": [ { "minCount": 0, "price": "string", "ponticPrice": "string", "implantPrice": "string" } ], "materialBands": {}, "catalog": { "perArch": true, "bands": [ { "minCount": 0, "price": "string", "ponticPrice": "string", "implantPrice": "string" } ], "materialBands": {} } }, "surcharges": { "implant": "string", "pontic": "string" }, "materialMarkups": {}, "optionPrices": {}, "switchPrices": {} } }' ``` --- # Delete a draft bundle rule `DELETE https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/bundles/{bundleId}` Documentation: https://docs.guidelab.co/api-reference/price-lists/deletePriceListBundleRule ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): - `versionId` (string) **(required)** (in: path): - `bundleId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `expectedRevision` (integer) **(required)**: ## Responses ### 200: Rule deleted - `deleted` (boolean) **(required)**: - `revision` (integer) **(required)**: ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/bundles/{bundleId}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "expectedRevision": 0 }' ``` --- # Set a draft bundle rule `PUT https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/bundles/{bundleId}` Documentation: https://docs.guidelab.co/api-reference/price-lists/upsertPriceListBundleRule ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): - `versionId` (string) **(required)** (in: path): - `bundleId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `expectedRevision` (integer) **(required)**: - `rule` (object) **(required)**: ## Responses ### 200: Rule saved - `rule` (object,null) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `priceListVersionId` (string) **(required)**: - `targetKind` (string) **(required)**: Values: `product`, `bundle`, `shipping_type` - `productId` (string,null) **(required)**: - `bundleId` (string,null) **(required)**: - `shippingTypeId` (string,null): - `fixedPrice` (string,null) **(required)**: - `discountPercent` (string,null) **(required)**: - `overrides` (object,null): - `bandTable` (object): - `perArch` (boolean) **(required)**: - `bands` (object[]) **(required)**: - `minCount` (integer) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `materialBands` (object): - `catalog` (object): - `perArch` (boolean) **(required)**: - `bands` (object[]) **(required)**: - `minCount` (integer) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `materialBands` (object): - `surcharges` (object): - `implant` (string): - `pontic` (string): - `materialMarkups` (object): - `optionPrices` (object): - `switchPrices` (object): - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] - `revision` (integer) **(required)**: ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/bundles/{bundleId}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "expectedRevision": 0, "rule": "string" }' ``` --- # Delete a draft shipping type rule `DELETE https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/shipping-types/{shippingTypeId}` Documentation: https://docs.guidelab.co/api-reference/price-lists/deletePriceListShippingTypeRule ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): - `versionId` (string) **(required)** (in: path): - `shippingTypeId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `expectedRevision` (integer) **(required)**: ## Responses ### 200: Rule deleted - `deleted` (boolean) **(required)**: - `revision` (integer) **(required)**: ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/shipping-types/{shippingTypeId}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "expectedRevision": 0 }' ``` --- # Set a draft shipping type rule `PUT https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/shipping-types/{shippingTypeId}` Documentation: https://docs.guidelab.co/api-reference/price-lists/upsertPriceListShippingTypeRule ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): - `versionId` (string) **(required)** (in: path): - `shippingTypeId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `expectedRevision` (integer) **(required)**: - `rule` (object) **(required)**: ## Responses ### 200: Rule saved - `rule` (object,null) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `priceListVersionId` (string) **(required)**: - `targetKind` (string) **(required)**: Values: `product`, `bundle`, `shipping_type` - `productId` (string,null) **(required)**: - `bundleId` (string,null) **(required)**: - `shippingTypeId` (string,null): - `fixedPrice` (string,null) **(required)**: - `discountPercent` (string,null) **(required)**: - `overrides` (object,null): - `bandTable` (object): - `perArch` (boolean) **(required)**: - `bands` (object[]) **(required)**: - `minCount` (integer) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `materialBands` (object): - `catalog` (object): - `perArch` (boolean) **(required)**: - `bands` (object[]) **(required)**: - `minCount` (integer) **(required)**: - `price` (string) **(required)**: - `ponticPrice` (string,null): - `implantPrice` (string,null): - `materialBands` (object): - `surcharges` (object): - `implant` (string): - `pontic` (string): - `materialMarkups` (object): - `optionPrices` (object): - `switchPrices` (object): - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] - `revision` (integer) **(required)**: ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/shipping-types/{shippingTypeId}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "expectedRevision": 0, "rule": "string" }' ``` --- # Publish an immutable effective-dated version `POST https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/publish` Documentation: https://docs.guidelab.co/api-reference/price-lists/publishPriceListVersion ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): - `versionId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `expectedRevision` (integer) **(required)**: - `activation` (object) **(required)**: - `effectiveUntil` (string,null): [date-time] - `supersedesVersionId` (string): ## Responses ### 200: Version published - `version` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `priceListId` (string) **(required)**: - `currency` (string) **(required)**: - `publicationNumber` (integer,null) **(required)**: - `defaultDiscountPercent` (string,null) **(required)**: - `revision` (integer) **(required)**: - `effectiveFrom` (string,null) **(required)**: [date-time] - `effectiveUntil` (string,null) **(required)**: [date-time] - `createdBy` (string) **(required)**: - `publishedAt` (string,null) **(required)**: [date-time] - `publishedBy` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: [date-time] - `cancelledBy` (string,null) **(required)**: - `endedEarlyAt` (string,null) **(required)**: [date-time] - `endedEarlyBy` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/publish" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "expectedRevision": 0, "activation": "string", "effectiveUntil": "string", "supersedesVersionId": "string" }' ``` --- # Cancel a future publication `POST https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/cancel` Documentation: https://docs.guidelab.co/api-reference/price-lists/cancelPriceListVersion ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): - `versionId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `expectedRevision` (integer) **(required)**: ## Responses ### 200: Publication cancelled - `version` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `priceListId` (string) **(required)**: - `currency` (string) **(required)**: - `publicationNumber` (integer,null) **(required)**: - `defaultDiscountPercent` (string,null) **(required)**: - `revision` (integer) **(required)**: - `effectiveFrom` (string,null) **(required)**: [date-time] - `effectiveUntil` (string,null) **(required)**: [date-time] - `createdBy` (string) **(required)**: - `publishedAt` (string,null) **(required)**: [date-time] - `publishedBy` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: [date-time] - `cancelledBy` (string,null) **(required)**: - `endedEarlyAt` (string,null) **(required)**: [date-time] - `endedEarlyBy` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/cancel" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "expectedRevision": 0 }' ``` --- # Shorten an active or future publication `POST https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/end` Documentation: https://docs.guidelab.co/api-reference/price-lists/endPriceListVersion ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `priceListId` (string) **(required)** (in: path): - `versionId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` ## Responses ### 200: Publication shortened - `version` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `priceListId` (string) **(required)**: - `currency` (string) **(required)**: - `publicationNumber` (integer,null) **(required)**: - `defaultDiscountPercent` (string,null) **(required)**: - `revision` (integer) **(required)**: - `effectiveFrom` (string,null) **(required)**: [date-time] - `effectiveUntil` (string,null) **(required)**: [date-time] - `createdBy` (string) **(required)**: - `publishedAt` (string,null) **(required)**: [date-time] - `publishedBy` (string,null) **(required)**: - `cancelledAt` (string,null) **(required)**: [date-time] - `cancelledBy` (string,null) **(required)**: - `endedEarlyAt` (string,null) **(required)**: [date-time] - `endedEarlyBy` (string,null) **(required)**: - `createdAt` (string,null) **(required)**: [date-time] - `updatedAt` (string,null) **(required)**: [date-time] ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/price-lists/{priceListId}/versions/{versionId}/end" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '"string"' ``` --- # Assign a stable price book to a partnership `PUT https://api.guidelab.co/price-lists/partnerships/{partnershipId}` Documentation: https://docs.guidelab.co/api-reference/price-lists/assignPartnershipPriceList ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `partnershipId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `priceListId` (string,null) **(required)**: ## Responses ### 200: Partnership assignment updated - `partnership` (object): ### 400: Invalid pricing lifecycle request ### 401: Unauthorized ### 403: Only lab managers may manage price lists ### 404: Price-list resource not found ### 409: Pricing lifecycle conflict ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/price-lists/partnerships/{partnershipId}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "priceListId": "string" }' ``` --- # Preview authoritative pricing without pinning an order `POST https://api.guidelab.co/price-lists/preview` Documentation: https://docs.guidelab.co/api-reference/price-lists/previewOrderPricing ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `labId` (string) **(required)**: - `clinicId` (string) **(required)**: - `patientId` (string,null): - `items` (object[]) **(required)**: - `productId` (string) **(required)**: - `toothGroups` (object[]): - `id` (string) **(required)**: - `type` (string) **(required)**: Values: `single`, `bridge` - `teeth` (object[]) **(required)**: - `fdi` (integer) **(required)**: - `role` (string) **(required)**: Values: `crown`, `pontic` - `support` (string): Values: `natural`, `implant` - `implantSystemId` (string): - `implantPlatform` (string): - `quantity` (integer): (default: `1`) - `materialId` (string): - `material` (string): - `shadeSystemId` (string): - `shadeOcclusal` (string): - `shadeMiddle` (string): - `shadeGingival` (string): - `shadeNotes` (string): - `defaultImplantSystemId` (string): - `defaultImplantPlatform` (string): - `notes` (string): - `customFieldValues` (object): - `value` (object): - `fileIds` (string[]): - `bundleId` (string): - `bundleInstanceId` (string): ## Responses ### 200: Authoritative pricing preview - `effectiveAt` (string,null) **(required)**: [date-time] - `selection` (string) **(required)**: Values: `assigned_price_list`, `lab_default_price_list`, `catalog` - `priceListId` (string,null) **(required)**: - `priceListVersionId` (string,null) **(required)**: - `currency` (string) **(required)**: - `items` (object[]) **(required)**: - `unitPrice` (string,null) **(required)**: - `totalPrice` (string,null) **(required)**: - `pricingSource` (string) **(required)**: Values: `fixed_rule`, `percent_rule`, `version_default_discount`, `catalog`, `custom_rule` - `priceListVersionId` (string,null) **(required)**: - `priceListRuleId` (string,null) **(required)**: - `priceListRuleTargetKind` (string,null) **(required)**: Values: `product`, `bundle`, `shipping_type`, `null` - `priceListProductRuleId` (string,null) **(required)**: - `priceListBundleRuleId` (string,null) **(required)**: ### 400: Catalog validation failed ### 401: Unauthorized ### 403: No active partnership access ### 404: Lab not found ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/price-lists/preview" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "labId": "string", "clinicId": "string", "patientId": "string", "items": [ { "productId": "string" } ] }' ``` --- # Get the lab's shipping rate table `GET https://api.guidelab.co/shipping/settings` Returns the lab's shipping zones, shipping types and weight-band prices, the lab's default VAT rate, the active physical products that have no weight yet (priced as 0 g), and the countries of the lab's partner clinics. Documentation: https://docs.guidelab.co/api-reference/shipping/getShippingSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: The lab's shipping rate table - `currency` (string) **(required)**: - `taxMode` (string) **(required)**: Values: `unconfigured`, `none`, `exclusive`, `inclusive` - `defaultTaxRate` (string,null) **(required)**: - `zones` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `isCatchAll` (boolean) **(required)**: - `countries` (string[]) **(required)**: - `types` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `method` (string) **(required)**: Values: `carrier`, `local_driver`, `collection` - `taxRate` (string,null) **(required)**: - `insurance` (object) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (integer) **(required)**: - `rates` (object[]) **(required)**: - `shippingTypeId` (string) **(required)**: - `zoneId` (string) **(required)**: - `minWeightGrams` (integer) **(required)**: - `price` (string) **(required)**: - `productsMissingWeight` (object) **(required)**: - `count` (integer) **(required)**: - `products` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `partnerCountries` (string[]) **(required)**: ### 401: Unauthorized ### 403: Only a lab can read or manage its shipping prices ## Example ```bash curl -X GET "https://api.guidelab.co/shipping/settings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Save the lab's whole shipping rate table `PUT https://api.guidelab.co/shipping/settings` Replaces the lab's shipping zones, types and prices with the given document. New rows carry client-generated ids so prices can reference a zone or type created in the same save. Omitted zones are deleted with their prices; an omitted shipping type is deleted unless an order still uses it (archive it with isActive=false instead). Orders keep the price they were sold with. Documentation: https://docs.guidelab.co/api-reference/shipping/replaceShippingSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `zones` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `isCatchAll` (boolean) **(required)**: - `countries` (string[]) **(required)**: - `types` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `method` (string) **(required)**: Values: `carrier`, `local_driver`, `collection` - `taxRate` (string,null) **(required)**: - `insurance` (object) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (integer) **(required)**: - `rates` (object[]) **(required)**: - `shippingTypeId` (string) **(required)**: - `zoneId` (string) **(required)**: - `minWeightGrams` (integer) **(required)**: - `price` (string) **(required)**: ## Responses ### 200: The saved rate table - `currency` (string) **(required)**: - `taxMode` (string) **(required)**: Values: `unconfigured`, `none`, `exclusive`, `inclusive` - `defaultTaxRate` (string,null) **(required)**: - `zones` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `isCatchAll` (boolean) **(required)**: - `countries` (string[]) **(required)**: - `types` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `method` (string) **(required)**: Values: `carrier`, `local_driver`, `collection` - `taxRate` (string,null) **(required)**: - `insurance` (object) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (integer) **(required)**: - `rates` (object[]) **(required)**: - `shippingTypeId` (string) **(required)**: - `zoneId` (string) **(required)**: - `minWeightGrams` (integer) **(required)**: - `price` (string) **(required)**: - `productsMissingWeight` (object) **(required)**: - `count` (integer) **(required)**: - `products` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `partnerCountries` (string[]) **(required)**: ### 400: Invalid document (code VALIDATION_FAILED) or a price the lab currency cannot represent (code shipping_price_precision) ### 401: Unauthorized ### 403: Only a lab can read or manage its shipping prices ### 409: A name is already used (shipping_name_taken) or an omitted shipping type is still used by orders (shipping_type_in_use) ## Example ```bash curl -X PUT "https://api.guidelab.co/shipping/settings" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "zones": [ { "id": "string", "name": "string", "isCatchAll": true, "countries": [ "string" ] } ], "types": [ { "id": "string", "name": "string", "method": "carrier", "taxRate": "string", "insurance": "string", "isActive": true, "sortOrder": 0 } ], "rates": [ { "shippingTypeId": "string", "zoneId": "string", "minWeightGrams": 0, "price": "string" } ] }' ``` --- # Get production settings `GET https://api.guidelab.co/production/settings` Retrieves the production configuration settings for the current lab. Returns an unpersisted default projection when no row exists; writes occur only through the manager-guarded update command. Documentation: https://docs.guidelab.co/api-reference/production/getProductionSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Lab production settings - `settings` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `isEnabled` (boolean) **(required)**: - `automaticScheduling` (boolean) **(required)**: - `customerRoomPreferences` (object[]) **(required)**: - `clinicId` (string) **(required)**: - `roomId` (string) **(required)**: - `memberId` (string) **(required)**: - `cutoffTime` (string) **(required)**: - `bufferDays` (number) **(required)**: - `showPricesInOrderDetails` (boolean) **(required)**: - `taskPageHeaders` (object,null) **(required)**: - `excludedCategoryIds` (array,null) **(required)**: - `excludedProductIds` (array,null) **(required)**: - `useDoneDate` (boolean) **(required)**: - `defaultUnitCapacity` (number) **(required)**: - `enableBarcodeScanning` (boolean) **(required)**: - `organizeByDate` (boolean) **(required)**: - `defaultSortField` (string) **(required)**: Values: `scheduledDate`, `dueDate`, `orderNumber`, `priority` - `defaultGroupBy` (string) **(required)**: Values: `room`, `assignee`, `status`, `date` - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — missing or invalid session ## Example ```bash curl -X GET "https://api.guidelab.co/production/settings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update production settings `PUT https://api.guidelab.co/production/settings` Updates the production configuration settings for the current lab. Documentation: https://docs.guidelab.co/api-reference/production/updateProductionSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `isEnabled` (boolean): - `automaticScheduling` (boolean): - `customerRoomPreferences` (object[]): - `clinicId` (string) **(required)**: - `roomId` (string) **(required)**: - `memberId` (string) **(required)**: - `cutoffTime` (string): - `bufferDays` (integer): - `showPricesInOrderDetails` (boolean): - `taskPageHeaders` (object): - `showClinic` (boolean): (default: `true`) - `showPatient` (boolean): (default: `true`) - `showOrderNumber` (boolean): (default: `true`) - `showDueDate` (boolean): (default: `true`) - `showProduct` (boolean): (default: `true`) - `excludedCategoryIds` (string[]): - `excludedProductIds` (string[]): - `useDoneDate` (boolean): - `defaultUnitCapacity` (integer): - `enableBarcodeScanning` (boolean): - `organizeByDate` (boolean): - `defaultSortField` (string): Values: `scheduledDate`, `dueDate`, `orderNumber`, `priority` - `defaultGroupBy` (string): Values: `room`, `assignee`, `status`, `date` ## Responses ### 200: Settings updated successfully - `settings` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `isEnabled` (boolean) **(required)**: - `automaticScheduling` (boolean) **(required)**: - `customerRoomPreferences` (object[]) **(required)**: - `clinicId` (string) **(required)**: - `roomId` (string) **(required)**: - `memberId` (string) **(required)**: - `cutoffTime` (string) **(required)**: - `bufferDays` (number) **(required)**: - `showPricesInOrderDetails` (boolean) **(required)**: - `taskPageHeaders` (object,null) **(required)**: - `excludedCategoryIds` (array,null) **(required)**: - `excludedProductIds` (array,null) **(required)**: - `useDoneDate` (boolean) **(required)**: - `defaultUnitCapacity` (number) **(required)**: - `enableBarcodeScanning` (boolean) **(required)**: - `organizeByDate` (boolean) **(required)**: - `defaultSortField` (string) **(required)**: Values: `scheduledDate`, `dueDate`, `orderNumber`, `priority` - `defaultGroupBy` (string) **(required)**: Values: `room`, `assignee`, `status`, `date` - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — missing or invalid session ## Example ```bash curl -X PUT "https://api.guidelab.co/production/settings" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Get lab-internal preferred operators for a customer `GET https://api.guidelab.co/production/settings/customers/{clinicId}` Documentation: https://docs.guidelab.co/api-reference/production/getCustomerProductionPreferences ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `clinicId` (string) **(required)** (in: path): ## Responses ### 200: Customer room preferences - `preferences` (object[]) **(required)**: - `roomId` (string) **(required)**: - `memberId` (string) **(required)**: - `memberName` (string,null) **(required)**: ### 400: Invalid preference ### 404: Customer not found ## Example ```bash curl -X GET "https://api.guidelab.co/production/settings/customers/{clinicId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Save one customer's preferred operators `PUT https://api.guidelab.co/production/settings/customers/{clinicId}` Documentation: https://docs.guidelab.co/api-reference/production/updateCustomerProductionPreferences ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `clinicId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `preferences` (object[]) **(required)**: - `roomId` (string) **(required)**: - `memberId` (string) **(required)**: ## Responses ### 200: Customer room preferences - `preferences` (object[]) **(required)**: - `roomId` (string) **(required)**: - `memberId` (string) **(required)**: - `memberName` (string,null) **(required)**: ### 400: Invalid preference ### 404: Customer not found ## Example ```bash curl -X PUT "https://api.guidelab.co/production/settings/customers/{clinicId}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "preferences": [ { "roomId": "string", "memberId": "string" } ] }' ``` --- # List production rooms `GET https://api.guidelab.co/production/rooms` Retrieves a paginated list of production rooms for the current lab. Supports filtering by active status and search by name. Documentation: https://docs.guidelab.co/api-reference/production/listProductionRooms ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` () (in: query): Default: `false` - `search` (string) (in: query): - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `50` ## Responses ### 200: Paginated list of production rooms - `rooms` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `color` (string) **(required)**: - `icon` (string,null) **(required)**: - `layoutType` (string) **(required)**: Values: `default`, `acceptance`, `shipping`, `production` - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — missing or invalid session ## Example ```bash curl -X GET "https://api.guidelab.co/production/rooms" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a production room `POST https://api.guidelab.co/production/rooms` Creates a new production room in the current lab. Automatically assigns the next sort order if not specified. Documentation: https://docs.guidelab.co/api-reference/production/createProductionRoom ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `description` (string): - `color` (string): (default: `#6366f1`) - `icon` (string): - `layoutType` (string): (default: `default`) Values: `default`, `acceptance`, `shipping`, `production` - `sortOrder` (integer): (default: `0`) - `isActive` (boolean): (default: `true`) ## Responses ### 201: Room created successfully - `room` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `color` (string) **(required)**: - `icon` (string,null) **(required)**: - `layoutType` (string) **(required)**: Values: `default`, `acceptance`, `shipping`, `production` - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — missing or invalid session ## Example ```bash curl -X POST "https://api.guidelab.co/production/rooms" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string" }' ``` --- # Reorder production rooms `PUT https://api.guidelab.co/production/rooms/reorder` Updates the sort order of multiple production rooms in a single batch operation. Documentation: https://docs.guidelab.co/api-reference/production/reorderProductionRooms ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `items` (object[]) **(required)**: - `id` (string) **(required)**: - `sortOrder` (integer) **(required)**: ## Responses ### 200: Rooms reordered successfully - `success` (boolean) **(required)**: ### 401: Unauthorized — missing or invalid session ## Example ```bash curl -X PUT "https://api.guidelab.co/production/rooms/reorder" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "items": [ { "id": "string", "sortOrder": 0 } ] }' ``` --- # Get a production room `GET https://api.guidelab.co/production/rooms/{id}` Retrieves a single production room by its ID. Only returns rooms belonging to the current lab. Documentation: https://docs.guidelab.co/api-reference/production/getProductionRoom ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Room ID ## Responses ### 200: Room details - `room` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `color` (string) **(required)**: - `icon` (string,null) **(required)**: - `layoutType` (string) **(required)**: Values: `default`, `acceptance`, `shipping`, `production` - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — missing or invalid session ### 404: Room not found ## Example ```bash curl -X GET "https://api.guidelab.co/production/rooms/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete a production room `DELETE https://api.guidelab.co/production/rooms/{id}` Permanently deletes a production room. Tasks assigned to this room will need to be reassigned. Documentation: https://docs.guidelab.co/api-reference/production/deleteProductionRoom ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Room ID ## Responses ### 200: Room deleted successfully - `success` (boolean) **(required)**: ### 401: Unauthorized — missing or invalid session ### 404: Room not found ### 409: Room is still used by an active order ## Example ```bash curl -X DELETE "https://api.guidelab.co/production/rooms/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a production room `PUT https://api.guidelab.co/production/rooms/{id}` Updates an existing production room's properties such as name, description, color, icon, sort order, or active status. Documentation: https://docs.guidelab.co/api-reference/production/updateProductionRoom ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Room ID ## Request Body Content-Type: `application/json` - `name` (string): - `description` (string): - `color` (string): - `icon` (string): - `layoutType` (string): Values: `default`, `acceptance`, `shipping`, `production` - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 200: Room updated successfully - `room` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `color` (string) **(required)**: - `icon` (string,null) **(required)**: - `layoutType` (string) **(required)**: Values: `default`, `acceptance`, `shipping`, `production` - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — missing or invalid session ### 404: Room not found ## Example ```bash curl -X PUT "https://api.guidelab.co/production/rooms/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # List orders assigned to a production room `GET https://api.guidelab.co/production/rooms/{id}/orders` Returns the orders relevant to a room together with the per-task done-ness (computed from orderActivity). Documentation: https://docs.guidelab.co/api-reference/production/listRoomRuntimeOrders ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `view` (string) (in: query): Values: `current`, `queue` Default: `current` - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `50` - `search` (string) (in: query): - `clinicId` (string) (in: query): - `clinicSearch` (string) (in: query): - `category` (string) (in: query): - `tray` (string) (in: query): Values: `assigned`, `unassigned` - `group` (string) (in: query): Values: `overdue`, `today`, `unplanned`, `upcoming`, `waiting` - `stageId` (string) (in: query): - `material` (string) (in: query): - `scheduledDate` (string) (in: query): Optional YYYY-MM-DD filter. When provided, only orders with at least one task scheduled for this date in the given room are returned. - `onlyMine` () (in: query): When true, only return orders whose current task in this room resolves to the current member (per-order override if present, otherwise the task's defaultAssigneeMemberId). Default: `false` ## Responses ### 200: Orders + tasks - `orders` (object[]) **(required)**: - `queue` (object): - `taskId` (string) **(required)**: - `taskName` (string) **(required)**: - `assignedToMemberId` (string,null) **(required)**: - `assigneeName` (string,null) **(required)**: - `assignmentReason` (string,null): - `effectiveDate` (string,null) **(required)**: - `group` (string) **(required)**: Values: `overdue`, `today`, `unplanned`, `upcoming`, `waiting` - `ready` (boolean) **(required)**: - `blocker` (string,null) **(required)**: Values: `earlier_task`, `clinic`, `hold`, `null` - `blockerName` (string,null) **(required)**: - `reviewNotes` (string,null): - `estimatedUnits` (number) **(required)**: - `estimatedMinutes` (number,null): - `plannedStartAt` (string,null): - `scheduleLocked` (boolean): - `plannedEndAt` (string,null): - `originalTargetAt` (string,null): - `timePlanningWarning` (string,null): - `planningWarning` (string,null) **(required)**: Values: `overload`, `no_operator`, `horizon`, `limit`, `calendar`, `null` - `deliveryDate` (string,null) **(required)**: - `orderPhaseId` (string) **(required)**: - `treatmentPhaseId` (string) **(required)**: - `phaseName` (string) **(required)**: - `phaseSortOrder` (integer) **(required)**: - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `status` (string) **(required)**: Values: `draft`, `submitted`, `active`, `completed`, `cancelled`, `on_hold` - `patient` (object,null) **(required)**: - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: - `clinic` (object,null) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `dentist` (string,null) **(required)**: - `items` (object[]) **(required)**: - `id` (string) **(required)**: - `productId` (string,null) **(required)**: - `productName` (string,null) **(required)**: - `productImageKey` (string,null) **(required)**: - `material` (string,null) **(required)**: - `quantity` (number) **(required)**: - `currentPhaseTaskId` (string,null) **(required)**: - `tasks` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `buttonLabel` (string,null) **(required)**: - `buttonDescription` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `color` (string,null) **(required)**: - `style` (string) **(required)**: Values: `primary`, `secondary`, `danger`, `default` - `completionTrigger` (string) **(required)**: Values: `acknowledge`, `assign_tray`, `upload_file`, `change_status`, `decision`, `set_manual_file_path`, `surgical_report`, `cad_approval`, `print_order`, `checklist`, `order_acceptance`, `generate_delivery_note` - `completionTriggerConfig` (object) **(required)**: - `sideEffects` (array) **(required)**: - `captureConfig` (object) **(required)**: - `requireNotes` (boolean): (default: `false`) - `requirePhoto` (boolean): (default: `false`) - `notesPlaceholder` (string): - `notesMaxLength` (integer): - `roomId` (string,null) **(required)**: - `sortOrder` (integer) **(required)**: - `advancesPhase` (boolean) **(required)**: - `done` (boolean) **(required)**: - `isCurrent` (boolean) **(required)**: - `assignedToMemberId` (string,null) **(required)**: - `scheduledDate` (string,null) **(required)**: - `estimatedUnits` (number,null): - `estimatedMinutes` (number,null): - `plannedStartAt` (string,null): - `scheduleLocked` (boolean): - `plannedEndAt` (string,null): - `originalTargetAt` (string,null): - `timePlanningWarning` (string,null): - `assignmentOrigin` (string,null): Values: `automatic`, `manual`, `null` - `assignmentReason` (string,null): - `planningWarning` (string,null): Values: `overload`, `no_operator`, `horizon`, `limit`, `calendar`, `null` - `notes` (string,null) **(required)**: - `phaseTasks` (object[]) **(required)**: - `id` (string) **(required)**: - `sortOrder` (integer) **(required)**: - `task` (object) **(required)**: - `name` (string) **(required)**: - `color` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `progress` (object) **(required)**: - `completed` (number) **(required)**: - `total` (number) **(required)**: - `hasOverdueTask` (boolean) **(required)**: - `trayId` (string,null) **(required)**: - `trayCode` (string,null) **(required)**: - `trayColor` (string,null) **(required)**: - `submittedAt` (string,null) **(required)**: - `dueDate` (string,null) **(required)**: - `plannedDate` (string,null) **(required)**: - `neededByDate` (string,null) **(required)**: - `filesDueBy` (string,null) **(required)**: - `pagination` (object): - `page` (integer) **(required)**: - `pageSize` (integer) **(required)**: - `total` (integer) **(required)**: - `totalOrders` (integer) **(required)**: - `mine` (integer) **(required)**: - `groups` (object) **(required)**: - `overdue` (number) **(required)**: - `today` (number) **(required)**: - `unplanned` (number) **(required)**: - `upcoming` (number) **(required)**: - `waiting` (number) **(required)**: - `overdueWaiting` (integer) **(required)**: ### 404: Room not found ## Example ```bash curl -X GET "https://api.guidelab.co/production/rooms/{id}/orders" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Per-day scheduled-stage counts for a production room `GET https://api.guidelab.co/production/rooms/{id}/schedule-counts` Returns a map of YYYY-MM-DD → number of distinct active stages with a task scheduled that day in the room. Powers the production date picker's per-day badges. Documentation: https://docs.guidelab.co/api-reference/production/getRoomScheduleCounts ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `startDate` (string) **(required)** (in: query): - `endDate` (string) **(required)** (in: query): ## Responses ### 200: Per-day counts - `counts` (object) **(required)**: Map of YYYY-MM-DD → number of distinct active stages scheduled in the room that day. (example: `[object Object]`) ### 404: Room not found ## Example ```bash curl -X GET "https://api.guidelab.co/production/rooms/{id}/schedule-counts" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List printers `GET https://api.guidelab.co/production/printers` Retrieves the list of printers for the current lab. Joins room and current batch. Documentation: https://docs.guidelab.co/api-reference/production/listPrinters ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `roomId` (string) (in: query): - `includeInactive` () (in: query): Default: `false` ## Responses ### 200: List of printers - `printers` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `roomId` (string) **(required)**: - `name` (string) **(required)**: - `model` (string,null) **(required)**: - `material` (string) **(required)**: - `status` (string) **(required)**: Values: `idle`, `running`, `finished`, `error`, `maintenance` - `currentBatchId` (string,null) **(required)**: - `sortOrder` (number,null) **(required)**: - `isActive` (boolean,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `room` (object,null): - `id` (string) **(required)**: - `name` (string) **(required)**: - `color` (string,null) **(required)**: - `currentBatch` (object,null): - `id` (string) **(required)**: - `name` (string) **(required)**: - `status` (string) **(required)**: - `startedAt` (string,null) **(required)**: - `orderItems` (object[]): - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string,null): - `productName` (string,null): - `material` (string,null): ### 401: Unauthorized — missing or invalid session ## Example ```bash curl -X GET "https://api.guidelab.co/production/printers" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a printer `POST https://api.guidelab.co/production/printers` Creates a new printer. The assigned room must belong to the current lab and have layoutType='production'. Documentation: https://docs.guidelab.co/api-reference/production/createPrinter ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `roomId` (string) **(required)**: - `name` (string) **(required)**: - `model` (string,null): - `material` (string): (default: ``) - `status` (string): (default: `idle`) Values: `idle`, `finished`, `error`, `maintenance` - `sortOrder` (integer): (default: `0`) - `isActive` (boolean): (default: `true`) ## Responses ### 201: Printer created - `printer` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `roomId` (string) **(required)**: - `name` (string) **(required)**: - `model` (string,null) **(required)**: - `material` (string) **(required)**: - `status` (string) **(required)**: Values: `idle`, `running`, `finished`, `error`, `maintenance` - `currentBatchId` (string,null) **(required)**: - `sortOrder` (number,null) **(required)**: - `isActive` (boolean,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `room` (object,null): - `id` (string) **(required)**: - `name` (string) **(required)**: - `color` (string,null) **(required)**: - `currentBatch` (object,null): - `id` (string) **(required)**: - `name` (string) **(required)**: - `status` (string) **(required)**: - `startedAt` (string,null) **(required)**: - `orderItems` (object[]): - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string,null): - `productName` (string,null): - `material` (string,null): ### 400: Assigned room is not a production room or other validation error ### 401: Unauthorized — missing or invalid session ### 404: Room not found ## Example ```bash curl -X POST "https://api.guidelab.co/production/printers" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "roomId": "string", "name": "string" }' ``` --- # Get a printer `GET https://api.guidelab.co/production/printers/{id}` Retrieves a single printer by ID within the current lab. Documentation: https://docs.guidelab.co/api-reference/production/getPrinter ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Printer ID ## Responses ### 200: Printer - `printer` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `roomId` (string) **(required)**: - `name` (string) **(required)**: - `model` (string,null) **(required)**: - `material` (string) **(required)**: - `status` (string) **(required)**: Values: `idle`, `running`, `finished`, `error`, `maintenance` - `currentBatchId` (string,null) **(required)**: - `sortOrder` (number,null) **(required)**: - `isActive` (boolean,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `room` (object,null): - `id` (string) **(required)**: - `name` (string) **(required)**: - `color` (string,null) **(required)**: - `currentBatch` (object,null): - `id` (string) **(required)**: - `name` (string) **(required)**: - `status` (string) **(required)**: - `startedAt` (string,null) **(required)**: - `orderItems` (object[]): - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string,null): - `productName` (string,null): - `material` (string,null): ### 401: Unauthorized — missing or invalid session ### 404: Printer not found ## Example ```bash curl -X GET "https://api.guidelab.co/production/printers/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete a printer `DELETE https://api.guidelab.co/production/printers/{id}` Permanently deletes a printer. Rejected while a print batch is active. Documentation: https://docs.guidelab.co/api-reference/production/deletePrinter ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Printer ID ## Responses ### 200: Printer deleted - `success` (boolean) **(required)**: ### 400: Printer has an active batch ### 401: Unauthorized — missing or invalid session ### 404: Printer not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/production/printers/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a printer `PUT https://api.guidelab.co/production/printers/{id}` Updates a printer. If roomId changes, the new room must be a production room in the current lab. Documentation: https://docs.guidelab.co/api-reference/production/updatePrinter ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Printer ID ## Request Body Content-Type: `application/json` - `roomId` (string): - `name` (string): - `model` (string,null): - `material` (string): - `status` (string): Values: `idle`, `finished`, `error`, `maintenance` - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 200: Printer updated - `printer` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `roomId` (string) **(required)**: - `name` (string) **(required)**: - `model` (string,null) **(required)**: - `material` (string) **(required)**: - `status` (string) **(required)**: Values: `idle`, `running`, `finished`, `error`, `maintenance` - `currentBatchId` (string,null) **(required)**: - `sortOrder` (number,null) **(required)**: - `isActive` (boolean,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `room` (object,null): - `id` (string) **(required)**: - `name` (string) **(required)**: - `color` (string,null) **(required)**: - `currentBatch` (object,null): - `id` (string) **(required)**: - `name` (string) **(required)**: - `status` (string) **(required)**: - `startedAt` (string,null) **(required)**: - `orderItems` (object[]): - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string,null): - `productName` (string,null): - `material` (string,null): ### 400: Invalid request ### 401: Unauthorized — missing or invalid session ### 404: Printer not found ### 409: Printer state changed concurrently ## Example ```bash curl -X PUT "https://api.guidelab.co/production/printers/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # List print batches `GET https://api.guidelab.co/production/print-batches` Retrieves print batches for the current lab. Filter by printerId, roomId, or status. Joins order items. Documentation: https://docs.guidelab.co/api-reference/production/listPrintBatches ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `printerId` (string) (in: query): - `roomId` (string) (in: query): - `status` (string) (in: query): Values: `queued`, `printing`, `completed`, `failed` - `activeOnly` () (in: query): Return only batches that are queued or printing, newest first. Default: `false` - `cursor` (string) (in: query): Opaque cursor returned by the previous page. Pages are ordered by creation time and ID, newest first. - `limit` (integer) (in: query): Maximum batches to return Default: `100` ## Responses ### 200: List of print batches - `batches` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `printerId` (string) **(required)**: - `roomId` (string) **(required)**: - `name` (string) **(required)**: - `status` (string) **(required)**: Values: `queued`, `printing`, `completed`, `failed` - `startedAt` (string,null) **(required)**: - `completedAt` (string,null) **(required)**: - `createdByMemberId` (string,null) **(required)**: - `completedByMemberId` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `failureReason` (string,null) **(required)**: - `durationSeconds` (integer,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `orderItems` (object[]): - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string,null) **(required)**: - `productName` (string,null) **(required)**: - `material` (string,null) **(required)**: - `orderItemsTruncated` (boolean) **(required)**: - `pagination` (object) **(required)**: - `limit` (integer) **(required)**: - `hasMore` (boolean) **(required)**: - `nextCursor` (string,null) **(required)**: ### 401: Unauthorized — missing or invalid session ## Example ```bash curl -X GET "https://api.guidelab.co/production/print-batches" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a print batch `POST https://api.guidelab.co/production/print-batches` Creates a new print batch in queued state. Verifies printer is idle with no current batch and that all order items belong to the lab. Generates a sequential name Batch-YYYYMMDD-XX. Documentation: https://docs.guidelab.co/api-reference/production/createPrintBatch ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `printerId` (string) **(required)**: - `orderItemIds` (string[]) **(required)**: - `notes` (string): ## Responses ### 201: Print batch created - `batch` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `printerId` (string) **(required)**: - `roomId` (string) **(required)**: - `name` (string) **(required)**: - `status` (string) **(required)**: Values: `queued`, `printing`, `completed`, `failed` - `startedAt` (string,null) **(required)**: - `completedAt` (string,null) **(required)**: - `createdByMemberId` (string,null) **(required)**: - `completedByMemberId` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `failureReason` (string,null) **(required)**: - `durationSeconds` (integer,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `orderItems` (object[]): - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string,null) **(required)**: - `productName` (string,null) **(required)**: - `material` (string,null) **(required)**: - `orderItemsTruncated` (boolean) **(required)**: ### 400: Printer not idle, inactive, or order items invalid ### 401: Unauthorized — missing or invalid session ### 404: Printer not found ## Example ```bash curl -X POST "https://api.guidelab.co/production/print-batches" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "printerId": "string", "orderItemIds": [ "string" ], "notes": "string" }' ``` --- # Start a print batch `POST https://api.guidelab.co/production/print-batches/{id}/start` Transitions a queued batch to printing. Printer running state is derived from the active batch. Documentation: https://docs.guidelab.co/api-reference/production/startPrintBatch ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Print batch ID ## Responses ### 200: Batch started - `batch` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `printerId` (string) **(required)**: - `roomId` (string) **(required)**: - `name` (string) **(required)**: - `status` (string) **(required)**: Values: `queued`, `printing`, `completed`, `failed` - `startedAt` (string,null) **(required)**: - `completedAt` (string,null) **(required)**: - `createdByMemberId` (string,null) **(required)**: - `completedByMemberId` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `failureReason` (string,null) **(required)**: - `durationSeconds` (integer,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `orderItems` (object[]): - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string,null) **(required)**: - `productName` (string,null) **(required)**: - `material` (string,null) **(required)**: - `orderItemsTruncated` (boolean) **(required)**: ### 400: Batch is not in a startable state ### 401: Unauthorized — missing or invalid session ### 404: Batch not found ### 409: Batch or printer state changed concurrently ## Example ```bash curl -X POST "https://api.guidelab.co/production/print-batches/{id}/start" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Complete a print batch `POST https://api.guidelab.co/production/print-batches/{id}/complete` Transitions a printing batch to completed and leaves the printer finished until a human clears it. Documentation: https://docs.guidelab.co/api-reference/production/completePrintBatch ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Print batch ID ## Responses ### 200: Batch completed - `batch` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `printerId` (string) **(required)**: - `roomId` (string) **(required)**: - `name` (string) **(required)**: - `status` (string) **(required)**: Values: `queued`, `printing`, `completed`, `failed` - `startedAt` (string,null) **(required)**: - `completedAt` (string,null) **(required)**: - `createdByMemberId` (string,null) **(required)**: - `completedByMemberId` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `failureReason` (string,null) **(required)**: - `durationSeconds` (integer,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `orderItems` (object[]): - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string,null) **(required)**: - `productName` (string,null) **(required)**: - `material` (string,null) **(required)**: - `orderItemsTruncated` (boolean) **(required)**: - `advanced` (string[]): - `skipped` (object[]): - `orderId` (string) **(required)**: - `reason` (string) **(required)**: - `requiresManualReview` (boolean) **(required)**: ### 400: Batch is not in a completable state ### 401: Unauthorized — missing or invalid session ### 404: Batch not found ### 409: Batch or printer state changed concurrently ## Example ```bash curl -X POST "https://api.guidelab.co/production/print-batches/{id}/complete" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Mark a print batch as failed `POST https://api.guidelab.co/production/print-batches/{id}/fail` Transitions a printing batch to failed, captures the reason, and leaves the printer in error until a human clears it. Documentation: https://docs.guidelab.co/api-reference/production/failPrintBatch ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Print batch ID ## Request Body Content-Type: `application/json` - `reason` (string): ## Responses ### 200: Batch marked failed - `batch` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `printerId` (string) **(required)**: - `roomId` (string) **(required)**: - `name` (string) **(required)**: - `status` (string) **(required)**: Values: `queued`, `printing`, `completed`, `failed` - `startedAt` (string,null) **(required)**: - `completedAt` (string,null) **(required)**: - `createdByMemberId` (string,null) **(required)**: - `completedByMemberId` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `failureReason` (string,null) **(required)**: - `durationSeconds` (integer,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `orderItems` (object[]): - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string,null) **(required)**: - `productName` (string,null) **(required)**: - `material` (string,null) **(required)**: - `orderItemsTruncated` (boolean) **(required)**: ### 400: Batch is not in a failable state ### 401: Unauthorized — missing or invalid session ### 404: Batch not found ### 409: Batch or printer state changed concurrently ## Example ```bash curl -X POST "https://api.guidelab.co/production/print-batches/{id}/fail" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "reason": "string" }' ``` --- # Get a print batch `GET https://api.guidelab.co/production/print-batches/{id}` Retrieves a single batch by ID with its order items. Documentation: https://docs.guidelab.co/api-reference/production/getPrintBatch ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Print batch ID ## Responses ### 200: Batch - `batch` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `printerId` (string) **(required)**: - `roomId` (string) **(required)**: - `name` (string) **(required)**: - `status` (string) **(required)**: Values: `queued`, `printing`, `completed`, `failed` - `startedAt` (string,null) **(required)**: - `completedAt` (string,null) **(required)**: - `createdByMemberId` (string,null) **(required)**: - `completedByMemberId` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `failureReason` (string,null) **(required)**: - `durationSeconds` (integer,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `orderItems` (object[]): - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string,null) **(required)**: - `productName` (string,null) **(required)**: - `material` (string,null) **(required)**: - `orderItemsTruncated` (boolean) **(required)**: ### 401: Unauthorized — missing or invalid session ### 404: Batch not found ## Example ```bash curl -X GET "https://api.guidelab.co/production/print-batches/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete a print batch `DELETE https://api.guidelab.co/production/print-batches/{id}` Deletes a print batch. Only allowed if status is queued. Documentation: https://docs.guidelab.co/api-reference/production/deletePrintBatch ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Print batch ID ## Responses ### 200: Batch deleted - `success` (boolean) **(required)**: ### 400: Batch is not in a deletable state ### 401: Unauthorized — missing or invalid session ### 404: Batch not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/production/print-batches/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List completed and failed print batches `GET https://api.guidelab.co/production/print-batches/history` Paginated history of batches with status completed or failed. Joins printer, room, and member display names. Ordered by completedAt DESC. Documentation: https://docs.guidelab.co/api-reference/production/listPrintBatchHistory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `printerId` (string) (in: query): - `roomId` (string) (in: query): - `status` (string) (in: query): Values: `completed`, `failed` - `operatorId` (string) (in: query): - `from` (string) (in: query): - `to` (string) (in: query): - `page` (integer) (in: query): Default: `1` - `pageSize` (integer) (in: query): Default: `50` ## Responses ### 200: History page - `items` (array) **(required)**: - `total` (number) **(required)**: - `page` (number) **(required)**: - `pageSize` (number) **(required)**: ### 401: Unauthorized — missing or invalid session ## Example ```bash curl -X GET "https://api.guidelab.co/production/print-batches/history" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Aggregate stats for a printer over a trailing window `GET https://api.guidelab.co/production/print-batches/printers/{printerId}/history-stats` Total runtime, average duration, and success rate over the last N days (default 30). Based on completed+failed batches. Documentation: https://docs.guidelab.co/api-reference/production/getPrinterHistoryStats ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `printerId` (string) **(required)** (in: path): Printer ID - `windowDays` (integer) (in: query): Default: `30` ## Responses ### 200: Aggregate stats ### 401: Unauthorized — missing or invalid session ### 404: Printer not found ## Example ```bash curl -X GET "https://api.guidelab.co/production/print-batches/printers/{printerId}/history-stats" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload a private checklist reference image `POST https://api.guidelab.co/production/tasks/checklist-image` Documentation: https://docs.guidelab.co/api-reference/production/uploadTaskChecklistImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Pending reference image - `imageId` (string) **(required)**: ### 400: Invalid image ### 413: Image too large ## Example ```bash curl -X POST "https://api.guidelab.co/production/tasks/checklist-image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Read a checklist reference image `GET https://api.guidelab.co/production/tasks/checklist-image/{imageId}` Documentation: https://docs.guidelab.co/api-reference/production/getTaskChecklistImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `imageId` (string) **(required)** (in: path): ## Responses ### 200: Image ### 404: Image not found ## Example ```bash curl -X GET "https://api.guidelab.co/production/tasks/checklist-image/{imageId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List production tasks `GET https://api.guidelab.co/production/tasks` Returns the task library for the current lab. Filter by trigger, active flag, or free-text name search. Documentation: https://docs.guidelab.co/api-reference/production/listProductionTasks ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `isActive` (string) (in: query): Values: `true`, `false` - `completionTrigger` (string) (in: query): Values: `acknowledge`, `assign_tray`, `upload_file`, `change_status`, `decision`, `set_manual_file_path`, `surgical_report`, `cad_approval`, `print_order`, `checklist`, `order_acceptance`, `generate_delivery_note` - `search` (string) (in: query): ## Responses ### 200: List of tasks - `tasks` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `buttonLabel` (string,null) **(required)**: - `buttonDescription` (string,null) **(required)**: - `iconDefault` (string,null) **(required)**: - `colorDefault` (string,null) **(required)**: - `styleDefault` (string) **(required)**: Values: `primary`, `secondary`, `danger`, `default` - `completionTrigger` (string) **(required)**: Values: `acknowledge`, `assign_tray`, `upload_file`, `change_status`, `decision`, `set_manual_file_path`, `surgical_report`, `cad_approval`, `print_order`, `checklist`, `order_acceptance`, `generate_delivery_note` - `completionTriggerConfig` (object) **(required)**: - `sideEffects` (array) **(required)**: - `captureConfig` (object) **(required)**: - `requireNotes` (boolean): (default: `false`) - `requirePhoto` (boolean): (default: `false`) - `notesPlaceholder` (string): - `notesMaxLength` (integer): - `defaultAssigneeMemberId` (string,null) **(required)**: - `fixedUnits` (integer): (default: `0`) - `perToothUnits` (integer): (default: `1`) - `baseMinutes` (integer,null): - `perToothMinutes` (integer): - `canSplit` (boolean): - `roomId` (string,null) **(required)**: - `riskNotes` (string,null) **(required)**: - `controlNotes` (string,null) **(required)**: - `equipmentId` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/production/tasks" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a task `POST https://api.guidelab.co/production/tasks` Create a new task definition in the lab's task library. Documentation: https://docs.guidelab.co/api-reference/production/createProductionTask ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `description` (string,null): - `buttonLabel` (string,null): - `buttonDescription` (string,null): - `iconDefault` (string,null): - `colorDefault` (string,null): - `styleDefault` (string): (default: `default`) Values: `primary`, `secondary`, `danger`, `default` - `completionTrigger` (string) **(required)**: Values: `acknowledge`, `assign_tray`, `upload_file`, `change_status`, `decision`, `set_manual_file_path`, `surgical_report`, `cad_approval`, `print_order`, `checklist`, `order_acceptance`, `generate_delivery_note` - `completionTriggerConfig` (object) **(required)**: - `sideEffects` (array): (default: ``) - `captureConfig` (object): (default: `[object Object]`) - `requireNotes` (boolean): (default: `false`) - `requirePhoto` (boolean): (default: `false`) - `notesPlaceholder` (string): - `notesMaxLength` (integer): - `defaultAssigneeMemberId` (string,null): - `fixedUnits` (integer): (default: `0`) - `perToothUnits` (integer): (default: `1`) - `baseMinutes` (integer,null): - `perToothMinutes` (integer): - `canSplit` (boolean): - `roomId` (string,null): - `riskNotes` (string,null): - `controlNotes` (string,null): - `equipmentId` (string,null): - `isActive` (boolean): (default: `true`) - `duplicateFromTaskId` (string): ## Responses ### 201: Task created - `task` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `buttonLabel` (string,null) **(required)**: - `buttonDescription` (string,null) **(required)**: - `iconDefault` (string,null) **(required)**: - `colorDefault` (string,null) **(required)**: - `styleDefault` (string) **(required)**: Values: `primary`, `secondary`, `danger`, `default` - `completionTrigger` (string) **(required)**: Values: `acknowledge`, `assign_tray`, `upload_file`, `change_status`, `decision`, `set_manual_file_path`, `surgical_report`, `cad_approval`, `print_order`, `checklist`, `order_acceptance`, `generate_delivery_note` - `completionTriggerConfig` (object) **(required)**: - `sideEffects` (array) **(required)**: - `captureConfig` (object) **(required)**: - `requireNotes` (boolean): (default: `false`) - `requirePhoto` (boolean): (default: `false`) - `notesPlaceholder` (string): - `notesMaxLength` (integer): - `defaultAssigneeMemberId` (string,null) **(required)**: - `fixedUnits` (integer): (default: `0`) - `perToothUnits` (integer): (default: `1`) - `baseMinutes` (integer,null): - `perToothMinutes` (integer): - `canSplit` (boolean): - `roomId` (string,null) **(required)**: - `riskNotes` (string,null) **(required)**: - `controlNotes` (string,null) **(required)**: - `equipmentId` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 404: Source task not found ## Example ```bash curl -X POST "https://api.guidelab.co/production/tasks" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "completionTrigger": "acknowledge", "completionTriggerConfig": "string" }' ``` --- # Get a task `GET https://api.guidelab.co/production/tasks/{id}` Documentation: https://docs.guidelab.co/api-reference/production/getProductionTask ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Task - `task` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `buttonLabel` (string,null) **(required)**: - `buttonDescription` (string,null) **(required)**: - `iconDefault` (string,null) **(required)**: - `colorDefault` (string,null) **(required)**: - `styleDefault` (string) **(required)**: Values: `primary`, `secondary`, `danger`, `default` - `completionTrigger` (string) **(required)**: Values: `acknowledge`, `assign_tray`, `upload_file`, `change_status`, `decision`, `set_manual_file_path`, `surgical_report`, `cad_approval`, `print_order`, `checklist`, `order_acceptance`, `generate_delivery_note` - `completionTriggerConfig` (object) **(required)**: - `sideEffects` (array) **(required)**: - `captureConfig` (object) **(required)**: - `requireNotes` (boolean): (default: `false`) - `requirePhoto` (boolean): (default: `false`) - `notesPlaceholder` (string): - `notesMaxLength` (integer): - `defaultAssigneeMemberId` (string,null) **(required)**: - `fixedUnits` (integer): (default: `0`) - `perToothUnits` (integer): (default: `1`) - `baseMinutes` (integer,null): - `perToothMinutes` (integer): - `canSplit` (boolean): - `roomId` (string,null) **(required)**: - `riskNotes` (string,null) **(required)**: - `controlNotes` (string,null) **(required)**: - `equipmentId` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 404: Task not found ## Example ```bash curl -X GET "https://api.guidelab.co/production/tasks/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a task `PATCH https://api.guidelab.co/production/tasks/{id}` Documentation: https://docs.guidelab.co/api-reference/production/updateProductionTask ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `name` (string): - `description` (string,null): - `buttonLabel` (string,null): - `buttonDescription` (string,null): - `iconDefault` (string,null): - `colorDefault` (string,null): - `styleDefault` (string): Values: `primary`, `secondary`, `danger`, `default` - `completionTrigger` (string): Values: `acknowledge`, `assign_tray`, `upload_file`, `change_status`, `decision`, `set_manual_file_path`, `surgical_report`, `cad_approval`, `print_order`, `checklist`, `order_acceptance`, `generate_delivery_note` - `completionTriggerConfig` (object): - `sideEffects` (array): - `captureConfig` (object): - `requireNotes` (boolean): (default: `false`) - `requirePhoto` (boolean): (default: `false`) - `notesPlaceholder` (string): - `notesMaxLength` (integer): - `defaultAssigneeMemberId` (string,null): - `fixedUnits` (integer): - `perToothUnits` (integer): - `baseMinutes` (integer,null): - `perToothMinutes` (integer): - `canSplit` (boolean): - `roomId` (string,null): - `riskNotes` (string,null): - `controlNotes` (string,null): - `equipmentId` (string,null): - `isActive` (boolean): ## Responses ### 200: Updated task - `task` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `buttonLabel` (string,null) **(required)**: - `buttonDescription` (string,null) **(required)**: - `iconDefault` (string,null) **(required)**: - `colorDefault` (string,null) **(required)**: - `styleDefault` (string) **(required)**: Values: `primary`, `secondary`, `danger`, `default` - `completionTrigger` (string) **(required)**: Values: `acknowledge`, `assign_tray`, `upload_file`, `change_status`, `decision`, `set_manual_file_path`, `surgical_report`, `cad_approval`, `print_order`, `checklist`, `order_acceptance`, `generate_delivery_note` - `completionTriggerConfig` (object) **(required)**: - `sideEffects` (array) **(required)**: - `captureConfig` (object) **(required)**: - `requireNotes` (boolean): (default: `false`) - `requirePhoto` (boolean): (default: `false`) - `notesPlaceholder` (string): - `notesMaxLength` (integer): - `defaultAssigneeMemberId` (string,null) **(required)**: - `fixedUnits` (integer): (default: `0`) - `perToothUnits` (integer): (default: `1`) - `baseMinutes` (integer,null): - `perToothMinutes` (integer): - `canSplit` (boolean): - `roomId` (string,null) **(required)**: - `riskNotes` (string,null) **(required)**: - `controlNotes` (string,null) **(required)**: - `equipmentId` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 404: Task not found ### 409: The update would leave an active treatment phase without an active task - `error` (string) **(required)**: ## Example ```bash curl -X PATCH "https://api.guidelab.co/production/tasks/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Delete a task `DELETE https://api.guidelab.co/production/tasks/{id}` Documentation: https://docs.guidelab.co/api-reference/production/deleteProductionTask ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Deleted - `success` (boolean) **(required)**: ### 404: Task not found ### 409: Task is still used by a treatment phase - `error` (string) **(required)**: ## Example ```bash curl -X DELETE "https://api.guidelab.co/production/tasks/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Bulk update tasks `POST https://api.guidelab.co/production/tasks/bulk` Activate, deactivate, set the default assignee, or delete several tasks at once. Only affects tasks owned by the current lab. Documentation: https://docs.guidelab.co/api-reference/production/bulkUpdateProductionTasks ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` ## Responses ### 200: Bulk result - `affected` (number) **(required)**: ### 409: A task is still referenced or deactivation would leave an active phase without a task - `error` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/production/tasks/bulk" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '"string"' ``` --- # Fire a task (runs trigger + side effects, logs activity) `POST https://api.guidelab.co/production/tasks/{orderPhaseTaskId}/fire` Single entry point for completing an immutable order phase task snapshot. Documentation: https://docs.guidelab.co/api-reference/production/fireProductionTask ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `orderPhaseTaskId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `orderId` (string) **(required)**: - `orderPhaseId` (string) **(required)**: - `decisionKey` (string): - `trayId` (string): - `fileIds` (string[]): - `printed` (boolean): Values: `true` - `deliveryNoteId` (string): - `checkedItemIds` (string[]): - `checklistFileIds` (object): - `orderDecision` (string): Values: `accept`, `refuse` - `holdReasonId` (string): - `holdNotes` (string): - `toStatus` (string): Values: `draft`, `submitted`, `active`, `completed`, `cancelled`, `on_hold` - `manualFilePath` (string): - `commandId` (string): [uuid] - `reportFileIds` (string[]): - `extraFileIds` (string[]): - `projectUrl` (string,null): [uri] - `notes` (string): - `attachmentIds` (string[]): - `confirmed` (boolean): ## Responses ### 200: Activity row recorded - `activity` (object) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderPhaseTaskId` (string,null) **(required)**: - `eventType` (string) **(required)**: Values: `task_fired`, `task_review_event`, `status_changed`, `phase_changed`, `tray_assigned`, `file_uploaded`, `note_added`, `system`, `hold_requirement_changed`, `order_updated`, `item_changed`, `file_removed`, `shipment_changed`, `payment_changed`, `authorization_signed` - `actorMemberId` (string,null) **(required)**: - `actorUserId` (string,null) **(required)**: - `phaseAtTime` (string,null) **(required)**: - `statusAtTime` (string,null) **(required)**: Values: `draft`, `submitted`, `active`, `completed`, `cancelled`, `on_hold`, `null` - `payload` (object) **(required)**: - `notes` (string,null) **(required)**: - `attachmentIds` (string[]) **(required)**: - `createdAt` (string) **(required)**: ### 400: Invalid trigger input ### 404: Task or order not found ### 409: Confirmation required ## Example ```bash curl -X POST "https://api.guidelab.co/production/tasks/{orderPhaseTaskId}/fire" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "orderId": "string", "orderPhaseId": "string" }' ``` --- # Get the current operator timer across rooms `GET https://api.guidelab.co/production/tasks/running` Documentation: https://docs.guidelab.co/api-reference/production/getRunningProductionTaskTime ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Running task - `task` (object,null) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `roomId` (string,null) **(required)**: - `phaseId` (string) **(required)**: - `time` (object) **(required)**: - `entries` (object[]) **(required)**: - `id` (string) **(required)**: - `memberId` (string) **(required)**: - `startedAt` (string) **(required)**: - `endedAt` (string,null) **(required)**: - `seconds` (number,null) **(required)**: - `source` (string) **(required)**: Values: `timer`, `activity_estimate`, `template_estimate`, `manual` - `canCorrect` (boolean) **(required)**: - `canControl` (boolean) **(required)**: - `totalSeconds` (number) **(required)**: - `runningMemberId` (string,null) **(required)**: - `runningSince` (string,null) **(required)**: - `estimatedMinutes` (number,null) **(required)**: - `originalTargetAt` (string,null) **(required)**: - `plannedStartAt` (string,null) **(required)**: - `plannedEndAt` (string,null) **(required)**: - `warning` (string,null) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/production/tasks/running" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List every running operator timer in the lab `GET https://api.guidelab.co/production/tasks/running/all` Documentation: https://docs.guidelab.co/api-reference/production/listLabRunningProductionTimers ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Running timers, oldest first - `timers` (object[]) **(required)**: - `entryId` (string) **(required)**: - `startedAt` (string) **(required)**: - `memberId` (string) **(required)**: - `userId` (string) **(required)**: - `userName` (string) **(required)**: - `taskId` (string) **(required)**: - `taskName` (string) **(required)**: - `roomId` (string,null) **(required)**: - `roomName` (string,null) **(required)**: - `roomColor` (string,null) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string) **(required)**: - `truncated` (boolean) **(required)**: ### 403: Lab access required ## Example ```bash curl -X GET "https://api.guidelab.co/production/tasks/running/all" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get task time and timer state `GET https://api.guidelab.co/production/tasks/{taskId}/time` Documentation: https://docs.guidelab.co/api-reference/production/getProductionTaskTime ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `taskId` (string) **(required)** (in: path): ## Responses ### 200: Task time - `entries` (object[]) **(required)**: - `id` (string) **(required)**: - `memberId` (string) **(required)**: - `startedAt` (string) **(required)**: - `endedAt` (string,null) **(required)**: - `seconds` (number,null) **(required)**: - `source` (string) **(required)**: Values: `timer`, `activity_estimate`, `template_estimate`, `manual` - `canCorrect` (boolean) **(required)**: - `canControl` (boolean) **(required)**: - `totalSeconds` (number) **(required)**: - `runningMemberId` (string,null) **(required)**: - `runningSince` (string,null) **(required)**: - `estimatedMinutes` (number,null) **(required)**: - `originalTargetAt` (string,null) **(required)**: - `plannedStartAt` (string,null) **(required)**: - `plannedEndAt` (string,null) **(required)**: - `warning` (string,null) **(required)**: ### 403: Room access required ### 404: Task not found ### 409: Task or timer changed ## Example ```bash curl -X GET "https://api.guidelab.co/production/tasks/{taskId}/time" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Start, pause or resume operator work `POST https://api.guidelab.co/production/tasks/{taskId}/time` Documentation: https://docs.guidelab.co/api-reference/production/updateProductionTaskTimer ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `taskId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `action` (string) **(required)**: Values: `start`, `pause`, `resume` - `commandId` (string) **(required)**: [uuid] ## Responses ### 200: Task time - `entries` (object[]) **(required)**: - `id` (string) **(required)**: - `memberId` (string) **(required)**: - `startedAt` (string) **(required)**: - `endedAt` (string,null) **(required)**: - `seconds` (number,null) **(required)**: - `source` (string) **(required)**: Values: `timer`, `activity_estimate`, `template_estimate`, `manual` - `canCorrect` (boolean) **(required)**: - `canControl` (boolean) **(required)**: - `totalSeconds` (number) **(required)**: - `runningMemberId` (string,null) **(required)**: - `runningSince` (string,null) **(required)**: - `estimatedMinutes` (number,null) **(required)**: - `originalTargetAt` (string,null) **(required)**: - `plannedStartAt` (string,null) **(required)**: - `plannedEndAt` (string,null) **(required)**: - `warning` (string,null) **(required)**: ### 403: Room access required ### 404: Task not found ### 409: Task or timer changed ## Example ```bash curl -X POST "https://api.guidelab.co/production/tasks/{taskId}/time" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "action": "start", "commandId": "string" }' ``` --- # Correct a closed time entry with an audit reason `PATCH https://api.guidelab.co/production/tasks/{taskId}/time/{entryId}` Documentation: https://docs.guidelab.co/api-reference/production/correctProductionTaskTime ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `taskId` (string) **(required)** (in: path): - `entryId` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `seconds` (integer) **(required)**: - `commandId` (string) **(required)**: [uuid] - `reason` (string) **(required)**: ## Responses ### 200: Task time - `entries` (object[]) **(required)**: - `id` (string) **(required)**: - `memberId` (string) **(required)**: - `startedAt` (string) **(required)**: - `endedAt` (string,null) **(required)**: - `seconds` (number,null) **(required)**: - `source` (string) **(required)**: Values: `timer`, `activity_estimate`, `template_estimate`, `manual` - `canCorrect` (boolean) **(required)**: - `canControl` (boolean) **(required)**: - `totalSeconds` (number) **(required)**: - `runningMemberId` (string,null) **(required)**: - `runningSince` (string,null) **(required)**: - `estimatedMinutes` (number,null) **(required)**: - `originalTargetAt` (string,null) **(required)**: - `plannedStartAt` (string,null) **(required)**: - `plannedEndAt` (string,null) **(required)**: - `warning` (string,null) **(required)**: ### 403: Room access required ### 404: Task not found ### 409: Task or timer changed ## Example ```bash curl -X PATCH "https://api.guidelab.co/production/tasks/{taskId}/time/{entryId}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "seconds": 0, "commandId": "string", "reason": "string" }' ``` --- # Set per-order assignee/date/notes for a task `POST https://api.guidelab.co/production/task-assignments` Updates assignee, date, or notes on the immutable task row for an order phase. Documentation: https://docs.guidelab.co/api-reference/production/updateOrderPhaseTaskAssignment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `orderPhaseTaskId` (string) **(required)**: - `orderId` (string) **(required)**: - `orderPhaseId` (string) **(required)**: - `assignedToMemberId` (string,null): - `scheduledDate` (string,null): - `plannedStartAt` (string,null): [date-time] - `scheduleLocked` (boolean): - `estimatedMinutes` (integer,null): - `notes` (string,null): ## Responses ### 200: Updated assignment - `assignment` (object) **(required)**: - `orderPhaseTaskId` (string) **(required)**: - `orderId` (string) **(required)**: - `orderPhaseId` (string) **(required)**: - `assignedToMemberId` (string,null) **(required)**: - `plannedStartAt` (string,null): - `plannedEndAt` (string,null): - `scheduleLocked` (boolean): - `estimatedMinutes` (number,null): - `scheduledDate` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ## Example ```bash curl -X POST "https://api.guidelab.co/production/task-assignments" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "orderPhaseTaskId": "string", "orderId": "string", "orderPhaseId": "string" }' ``` --- # Clear assignment fields for an order phase task `DELETE https://api.guidelab.co/production/task-assignments` Documentation: https://docs.guidelab.co/api-reference/production/clearOrderPhaseTaskAssignment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `orderPhaseTaskId` (string) **(required)**: - `orderId` (string) **(required)**: - `orderPhaseId` (string) **(required)**: ## Responses ### 200: Cleared - `success` (boolean) **(required)**: ## Example ```bash curl -X DELETE "https://api.guidelab.co/production/task-assignments" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "orderPhaseTaskId": "string", "orderId": "string", "orderPhaseId": "string" }' ``` --- # Cronologia: list activity rows for an order `GET https://api.guidelab.co/production/orders/{id}/activity` Returns activity rows ordered by createdAt DESC, with the actor resolved for display. Powers the order History rail and acts as the source of truth for the per-phase-visit done-ness calculation. Clinic callers receive only clinic-safe event types, never activity notes, and never lab-only fields inside an order_updated change list. Documentation: https://docs.guidelab.co/api-reference/production/listOrderActivity ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `eventType` (string) (in: query): Values: `task_fired`, `task_review_event`, `status_changed`, `phase_changed`, `tray_assigned`, `file_uploaded`, `note_added`, `system`, `hold_requirement_changed`, `order_updated`, `item_changed`, `file_removed`, `shipment_changed`, `payment_changed`, `authorization_signed` - `limit` (integer) (in: query): Default: `100` ## Responses ### 200: Activity rows - `activity` (object[]) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderPhaseTaskId` (string,null) **(required)**: - `eventType` (string) **(required)**: Values: `task_fired`, `task_review_event`, `status_changed`, `phase_changed`, `tray_assigned`, `file_uploaded`, `note_added`, `system`, `hold_requirement_changed`, `order_updated`, `item_changed`, `file_removed`, `shipment_changed`, `payment_changed`, `authorization_signed` - `actorMemberId` (string,null) **(required)**: - `actorUserId` (string,null) **(required)**: - `phaseAtTime` (string,null) **(required)**: - `statusAtTime` (string,null) **(required)**: Values: `draft`, `submitted`, `active`, `completed`, `cancelled`, `on_hold`, `null` - `payload` (object) **(required)**: - `notes` (string,null) **(required)**: - `attachmentIds` (string[]) **(required)**: - `createdAt` (string) **(required)**: - `actorName` (string) **(required)**: - `actorImage` (string,null) **(required)**: - `actorKind` (string) **(required)**: Values: `system`, `user`, `anonymized_user` ### 404: Order not found ## Example ```bash curl -X GET "https://api.guidelab.co/production/orders/{id}/activity" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get the task plan for an order `GET https://api.guidelab.co/production/orders/{id}/task-plan` Returns every task applicable to this order grouped by phase → room → task, with assignment overrides and done-ness. Documentation: https://docs.guidelab.co/api-reference/production/getOrderTaskPlan ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Task plan - `phases` (object[]) **(required)**: - `orderPhaseId` (string) **(required)**: - `treatmentPhaseId` (string) **(required)**: - `name` (string) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `workTrayId` (string,null) **(required)**: - `rooms` (object[]) **(required)**: - `roomId` (string) **(required)**: - `name` (string) **(required)**: - `color` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `layoutType` (string) **(required)**: - `tasks` (object[]) **(required)**: - `task` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `buttonLabel` (string,null) **(required)**: - `buttonDescription` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `color` (string,null) **(required)**: - `style` (string) **(required)**: Values: `primary`, `secondary`, `danger`, `default` - `completionTrigger` (string) **(required)**: Values: `acknowledge`, `assign_tray`, `upload_file`, `change_status`, `decision`, `set_manual_file_path`, `surgical_report`, `cad_approval`, `print_order`, `checklist`, `order_acceptance`, `generate_delivery_note` - `completionTriggerConfig` (object) **(required)**: - `sideEffects` (array) **(required)**: - `captureConfig` (object) **(required)**: - `requireNotes` (boolean): (default: `false`) - `requirePhoto` (boolean): (default: `false`) - `notesPlaceholder` (string): - `notesMaxLength` (integer): - `roomId` (string,null) **(required)**: - `sortOrder` (integer) **(required)**: - `advancesPhase` (boolean) **(required)**: - `done` (boolean) **(required)**: - `isCurrent` (boolean) **(required)**: - `assignedToMemberId` (string,null) **(required)**: - `scheduledDate` (string,null) **(required)**: - `estimatedUnits` (number,null): - `estimatedMinutes` (number,null): - `plannedStartAt` (string,null): - `scheduleLocked` (boolean): - `plannedEndAt` (string,null): - `originalTargetAt` (string,null): - `timePlanningWarning` (string,null): - `assignmentOrigin` (string,null): Values: `automatic`, `manual`, `null` - `assignmentReason` (string,null): - `planningWarning` (string,null): Values: `overload`, `no_operator`, `horizon`, `limit`, `calendar`, `null` - `notes` (string,null) **(required)**: ### 404: Order not found ## Example ```bash curl -X GET "https://api.guidelab.co/production/orders/{id}/task-plan" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Storico: lab-wide activity feed `GET https://api.guidelab.co/production/activity` Returns activity rows across all orders in the current lab, joined with order/member/user/task metadata. Supports event-type filter and createdAt cursor-based pagination. Documentation: https://docs.guidelab.co/api-reference/production/listProductionActivityFeed ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `days` (integer) (in: query): - `limit` (integer) (in: query): Default: `100` - `cursor` (string) (in: query): ISO timestamp of the last item returned in the previous page. Items with createdAt < cursor are returned. - `eventType` (string) (in: query): Values: `task_fired`, `task_review_event`, `status_changed`, `phase_changed`, `tray_assigned`, `file_uploaded`, `note_added`, `system`, `hold_requirement_changed`, `order_updated`, `item_changed`, `file_removed`, `shipment_changed`, `payment_changed`, `authorization_signed` ## Responses ### 200: Activity feed items - `items` (object[]) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string) **(required)**: - `eventType` (string) **(required)**: Values: `task_fired`, `task_review_event`, `status_changed`, `phase_changed`, `tray_assigned`, `file_uploaded`, `note_added`, `system`, `hold_requirement_changed`, `order_updated`, `item_changed`, `file_removed`, `shipment_changed`, `payment_changed`, `authorization_signed` - `taskName` (string,null) **(required)**: - `actorName` (string) **(required)**: - `isSystemActor` (boolean) **(required)**: - `actorKind` (string) **(required)**: Values: `system`, `user`, `anonymized_user` - `createdAt` (string) **(required)**: - `payload` (object) **(required)**: - `phaseAtTime` (string,null) **(required)**: - `statusAtTime` (string,null) **(required)**: Values: `draft`, `submitted`, `active`, `completed`, `cancelled`, `on_hold`, `null` - `nextCursor` (string): ## Example ```bash curl -X GET "https://api.guidelab.co/production/activity" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List production teammates `GET https://api.guidelab.co/production/teammates` Retrieves a paginated list of lab members with their production room assignments. Supports filtering by room and search by name or email. Documentation: https://docs.guidelab.co/api-reference/production/listProductionTeammates ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `memberId` (string) (in: query): - `canWorkOnly` () (in: query): Default: `false` - `roomId` (string) (in: query): - `search` (string) (in: query): - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `50` ## Responses ### 200: Paginated list of teammates with room assignments - `teammates` (object[]) **(required)**: - `id` (string) **(required)**: - `userId` (string) **(required)**: - `role` (string) **(required)**: - `user` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `email` (string) **(required)**: - `image` (string,null) **(required)**: - `rooms` (object[]) **(required)**: - `id` (string) **(required)**: - `memberId` (string) **(required)**: - `roomId` (string) **(required)**: - `canView` (boolean) **(required)**: - `canWork` (boolean) **(required)**: - `canAssign` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `room` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `color` (string) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — missing or invalid session ## Example ```bash curl -X GET "https://api.guidelab.co/production/teammates" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get teammate room assignments `GET https://api.guidelab.co/production/teammates/{memberId}/rooms` Retrieves all production room assignments for a specific lab member, including room details and permission flags (canView, canWork, canAssign). Documentation: https://docs.guidelab.co/api-reference/production/getTeammateRoomAssignments ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `memberId` (string) **(required)** (in: path): Member ID ## Responses ### 200: List of room assignments with permissions - `rooms` (object[]) **(required)**: - `id` (string) **(required)**: - `memberId` (string) **(required)**: - `roomId` (string) **(required)**: - `canView` (boolean) **(required)**: - `canWork` (boolean) **(required)**: - `canAssign` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `room` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `color` (string) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — missing or invalid session ### 404: Member not found ## Example ```bash curl -X GET "https://api.guidelab.co/production/teammates/{memberId}/rooms" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Assign a room to a teammate `POST https://api.guidelab.co/production/teammates/{memberId}/rooms` Assigns a production room to a lab member with configurable permissions (canView, canWork, canAssign). Returns a 409 if the member is already assigned to the room. Documentation: https://docs.guidelab.co/api-reference/production/assignTeammateRoom ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `memberId` (string) **(required)** (in: path): Member ID ## Responses ### 201: Room assignment created successfully - `assignment` (object) **(required)**: - `id` (string) **(required)**: - `memberId` (string) **(required)**: - `roomId` (string) **(required)**: - `canView` (boolean) **(required)**: - `canWork` (boolean) **(required)**: - `canAssign` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `room` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `color` (string) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — missing or invalid session ### 404: Member or room not found ### 409: Member is already assigned to this room ## Example ```bash curl -X POST "https://api.guidelab.co/production/teammates/{memberId}/rooms" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Remove a teammate room assignment `DELETE https://api.guidelab.co/production/teammates/{memberId}/rooms` Removes a production room assignment from a lab member. The roomId must be provided in the request body. Documentation: https://docs.guidelab.co/api-reference/production/removeTeammateRoomAssignment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `memberId` (string) **(required)** (in: path): Member ID ## Responses ### 200: Room assignment removed successfully - `success` (boolean) **(required)**: ### 401: Unauthorized — missing or invalid session ### 404: Member or room assignment not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/production/teammates/{memberId}/rooms" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update teammate room permissions `PUT https://api.guidelab.co/production/teammates/{memberId}/rooms` Updates a member's permissions for a specific production room assignment, including canView, canWork, and canAssign flags. Documentation: https://docs.guidelab.co/api-reference/production/updateTeammateRoomPermissions ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `memberId` (string) **(required)** (in: path): Member ID ## Request Body Content-Type: `application/json` - `canView` (boolean): - `canWork` (boolean): - `canAssign` (boolean): - `roomId` (string) **(required)**: ## Responses ### 200: Room permissions updated successfully - `assignment` (object) **(required)**: - `id` (string) **(required)**: - `memberId` (string) **(required)**: - `roomId` (string) **(required)**: - `canView` (boolean) **(required)**: - `canWork` (boolean) **(required)**: - `canAssign` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — missing or invalid session ### 404: Member or room assignment not found ## Example ```bash curl -X PUT "https://api.guidelab.co/production/teammates/{memberId}/rooms" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "canView": true, "canWork": true, "canAssign": true, "roomId": "string" }' ``` --- # Get teammate production settings `GET https://api.guidelab.co/production/teammates/{memberId}/settings` Retrieves production-specific settings for a lab member, including working intervals, access level, default room, and unassigned task visibility. Returns defaults if no settings are configured. Documentation: https://docs.guidelab.co/api-reference/production/getTeammateSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `memberId` (string) **(required)** (in: path): Member ID ## Responses ### 200: Member production settings - `settings` (object) **(required)**: - `memberId` (string) **(required)**: - `dailyUnitCapacity` (number) **(required)**: - `workingIntervals` (object[]): (default: ``) - `weekday` (integer) **(required)**: - `startMinute` (integer) **(required)**: - `endMinute` (integer) **(required)**: - `unavailableDates` (object[]): (default: ``) - `startDate` (string) **(required)**: - `endDate` (string) **(required)**: - `accessLevel` (string) **(required)**: - `showUnassignedTasks` (boolean) **(required)**: - `defaultRoomId` (string,null) **(required)**: - `defaultRoom` (object,null) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `color` (string) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — missing or invalid session ### 404: Member not found ## Example ```bash curl -X GET "https://api.guidelab.co/production/teammates/{memberId}/settings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update teammate production settings `PUT https://api.guidelab.co/production/teammates/{memberId}/settings` Creates or updates production-specific settings for a lab member. Upserts the settings record, creating one with defaults if it does not exist yet. Documentation: https://docs.guidelab.co/api-reference/production/updateTeammateSettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `memberId` (string) **(required)** (in: path): Member ID ## Request Body Content-Type: `application/json` - `workingIntervals` (object[]): (default: ``) - `weekday` (integer) **(required)**: - `startMinute` (integer) **(required)**: - `endMinute` (integer) **(required)**: - `dailyUnitCapacity` (integer): (default: `100`) - `unavailableDates` (object[]): (default: ``) - `startDate` (string) **(required)**: - `endDate` (string) **(required)**: - `accessLevel` (string): (default: `full`) Values: `full`, `single`, `strict` - `showUnassignedTasks` (boolean): (default: `true`) - `defaultRoomId` (string,null): ## Responses ### 200: Member settings updated successfully - `settings` (object) **(required)**: - `id` (string) **(required)**: - `memberId` (string) **(required)**: - `dailyUnitCapacity` (number) **(required)**: - `workingIntervals` (object[]): (default: ``) - `weekday` (integer) **(required)**: - `startMinute` (integer) **(required)**: - `endMinute` (integer) **(required)**: - `unavailableDates` (object[]): (default: ``) - `startDate` (string) **(required)**: - `endDate` (string) **(required)**: - `accessLevel` (string) **(required)**: - `showUnassignedTasks` (boolean) **(required)**: - `defaultRoomId` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — missing or invalid session ### 404: Member not found ## Example ```bash curl -X PUT "https://api.guidelab.co/production/teammates/{memberId}/settings" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "workingIntervals": [ { "weekday": 0, "startMinute": 0, "endMinute": 0 } ], "dailyUnitCapacity": 0, "unavailableDates": [ { "startDate": "string", "endDate": "string" } ], "accessLevel": "full", "showUnassignedTasks": true, "defaultRoomId": "string" }' ``` --- # Task time, delays and delivery risk `GET https://api.guidelab.co/production/statistics/time` Documentation: https://docs.guidelab.co/api-reference/production/getProductionTimeReport ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `startDate` (string) (in: query): - `endDate` (string) (in: query): - `roomId` (string) (in: query): - `memberId` (string) (in: query): - `clinicId` (string) (in: query): - `onlyDelayed` () (in: query): Default: `false` - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `50` ## Responses ### 200: Bounded production time report - `rows` (object[]) **(required)**: - `taskId` (string) **(required)**: - `phaseId` (string) **(required)**: - `taskName` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string) **(required)**: - `roomName` (string,null) **(required)**: - `roomId` (string,null) **(required)**: - `memberName` (string,null) **(required)**: - `clinicName` (string,null) **(required)**: - `estimatedMinutes` (number,null) **(required)**: - `recordedSeconds` (number) **(required)**: - `inferredSeconds` (number) **(required)**: - `originalTargetAt` (string,null) **(required)**: - `plannedEndAt` (string,null) **(required)**: - `completedAt` (string,null) **(required)**: - `warning` (string,null) **(required)**: - `late` (boolean) **(required)**: - `deliveryRisk` (boolean) **(required)**: - `running` (boolean) **(required)**: - `total` (number) **(required)**: - `late` (number) **(required)**: - `deliveryRisk` (number) **(required)**: - `running` (number) **(required)**: - `completed` (number) **(required)**: - `recordedSeconds` (number) **(required)**: - `inferredSeconds` (number) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `planningIssue` (string,null) **(required)**: ### 400: Invalid reporting period ### 422: Reporting budget exceeded; narrow the period or filters ## Example ```bash curl -X GET "https://api.guidelab.co/production/statistics/time" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get production statistics overview `GET https://api.guidelab.co/production/statistics/overview` Returns a minimal production statistics overview computed from the activity log. Detailed per-room / per-member breakdowns are TODO under the new task model. Documentation: https://docs.guidelab.co/api-reference/production/getProductionStatisticsOverview ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `startDate` (string) (in: query): - `endDate` (string) (in: query): ## Responses ### 200: Statistics overview - `overview` (object) **(required)**: - `totalTasks` (number) **(required)**: - `completedTasks` (number) **(required)**: - `inProgressTasks` (number) **(required)**: - `pendingTasks` (number) **(required)**: - `averageCompletionTime` (number,null) **(required)**: - `capacityUsage` (number) **(required)**: - `byRoom` (array): (default: ``) - `byMember` (array): (default: ``) - `dailyTrend` (object[]) **(required)**: - `date` (string) **(required)**: - `completed` (number) **(required)**: - `total` (number) **(required)**: - `dateRange` (object) **(required)**: - `startDate` (string) **(required)**: - `endDate` (string) **(required)**: ### 409: Organization timezone is not a valid IANA zone - `error` (string) **(required)**: - `code` (string) **(required)**: Values: `ORGANIZATION_CONFIGURATION_INVALID` ## Example ```bash curl -X GET "https://api.guidelab.co/production/statistics/overview" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List inventory categories `GET https://api.guidelab.co/inventory/categories` Returns all inventory categories for the current organization, ordered by sort order and name. Optionally includes inactive categories. Documentation: https://docs.guidelab.co/api-reference/inventory/listInventoryCategories ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` (string) (in: query): Set to 'true' to include inactive categories ## Responses ### 200: List of inventory categories - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `parentId` (string,null) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/inventory/categories" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create an inventory category `POST https://api.guidelab.co/inventory/categories` Creates a new inventory category for organizing inventory items. Supports hierarchical parent-child relationships. Documentation: https://docs.guidelab.co/api-reference/inventory/createInventoryCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `description` (string): - `parentId` (string): - `icon` (string): - `sortOrder` (integer): (default: `0`) - `isActive` (boolean): (default: `true`) ## Responses ### 201: Category created successfully - `data` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `parentId` (string,null) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 401: Unauthorized - valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/inventory/categories" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string", "parentId": "string", "icon": "string", "sortOrder": 0, "isActive": true }' ``` --- # Reorder inventory categories `POST https://api.guidelab.co/inventory/categories/reorder` Updates the sort order of inventory categories based on the provided ordered list of category IDs. All IDs must belong to the current organization. Documentation: https://docs.guidelab.co/api-reference/inventory/reorderInventoryCategories ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `categoryIds` (string[]) **(required)**: ## Responses ### 200: Categories reordered successfully - `success` (boolean) **(required)**: ### 400: Invalid request body ### 401: Unauthorized - valid session required ### 404: One or more categories not found ## Example ```bash curl -X POST "https://api.guidelab.co/inventory/categories/reorder" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "categoryIds": [ "string" ] }' ``` --- # Seed default inventory categories `POST https://api.guidelab.co/inventory/categories/seed` Populates the organization with preset inventory categories based on the organization type (lab or clinic). This is idempotent and will not re-seed if already done. Documentation: https://docs.guidelab.co/api-reference/inventory/seedInventoryCategories ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Categories already seeded - `data` (object) **(required)**: - `alreadySeeded` (boolean): - `seeded` (number): ### 201: Default categories seeded successfully - `data` (object) **(required)**: - `seeded` (number) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/inventory/categories/seed" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get an inventory category `GET https://api.guidelab.co/inventory/categories/{id}` Retrieves the full details of a single inventory category by its ID. Documentation: https://docs.guidelab.co/api-reference/inventory/getInventoryCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Category ID ## Responses ### 200: Category details - `data` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `parentId` (string,null) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized - valid session required ### 404: Category not found ## Example ```bash curl -X GET "https://api.guidelab.co/inventory/categories/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete an inventory category `DELETE https://api.guidelab.co/inventory/categories/{id}` Permanently deletes an inventory category. Items in this category will lose their category association. Documentation: https://docs.guidelab.co/api-reference/inventory/deleteInventoryCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Category ID ## Responses ### 200: Category deleted successfully - `success` (boolean) **(required)**: ### 401: Unauthorized - valid session required ### 404: Category not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/inventory/categories/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update an inventory category `PUT https://api.guidelab.co/inventory/categories/{id}` Updates the properties of an existing inventory category such as name, description, icon, or active status. Documentation: https://docs.guidelab.co/api-reference/inventory/updateInventoryCategory ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Category ID ## Request Body Content-Type: `application/json` - `name` (string): - `description` (string): - `parentId` (string): - `icon` (string): - `sortOrder` (integer): - `isActive` (boolean): ## Responses ### 200: Updated category - `data` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `parentId` (string,null) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `icon` (string,null) **(required)**: - `sortOrder` (number) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 401: Unauthorized - valid session required ### 404: Category not found ## Example ```bash curl -X PUT "https://api.guidelab.co/inventory/categories/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string", "parentId": "string", "icon": "string", "sortOrder": 0, "isActive": true }' ``` --- # List inventory items `GET https://api.guidelab.co/inventory/items` Returns a paginated list of inventory items for the current organization. Supports filtering by category, supplier, low stock, expiring soon, and search by name or SKU. Documentation: https://docs.guidelab.co/api-reference/inventory/listInventoryItems ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `search` (string) (in: query): - `categoryId` (string) (in: query): - `supplierId` (string) (in: query): - `lowStock` () (in: query): Default: `false` - `expiringSoon` () (in: query): Default: `false` - `includeInactive` () (in: query): Default: `false` - `sortBy` (string) (in: query): Values: `name`, `sku`, `currentQuantity`, `unitCost`, `expirationDate`, `createdAt` Default: `name` - `sortOrder` (string) (in: query): Values: `asc`, `desc` Default: `asc` ## Responses ### 200: Paginated list of inventory items with category and supplier names - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `supplierId` (string,null) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `description` (string,null) **(required)**: - `unit` (string) **(required)**: - `currentQuantity` (string) **(required)**: - `minQuantity` (string,null) **(required)**: - `maxQuantity` (string,null) **(required)**: - `unitCost` (string,null) **(required)**: - `currency` (string) **(required)**: - `storageLocation` (string,null) **(required)**: - `lotNumber` (string,null) **(required)**: - `expirationDate` (string,null) **(required)**: - `barcode` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `categoryName` (string,null) **(required)**: - `supplierName` (string,null) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/inventory/items" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create an inventory item `POST https://api.guidelab.co/inventory/items` Creates a new inventory item in the organization's catalog. If the initial quantity is greater than zero, an initial stock adjustment is automatically recorded. Documentation: https://docs.guidelab.co/api-reference/inventory/createInventoryItem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `sku` (string): - `description` (string): - `categoryId` (string): - `supplierId` (string): - `unit` (string): (default: `pcs`) Values: `pcs`, `g`, `kg`, `ml`, `L`, `box`, `roll`, `pack`, `set`, `pair`, `sheet`, `tube`, `bottle`, `cartridge`, `syringe`, `capsule` - `currentQuantity` (object): (default: `0`) - `minQuantity` (object): - `maxQuantity` (object): - `unitCost` (string,null): - `currency` (string): (default: `GBP`) Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `storageLocation` (string): - `lotNumber` (string): - `expirationDate` (string,null): - `barcode` (string): - `notes` (string): ## Responses ### 201: Inventory item created successfully - `data` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `unit` (string) **(required)**: - `currentQuantity` (string) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 401: Unauthorized - valid session required ### 409: An item with this SKU already exists ## Example ```bash curl -X POST "https://api.guidelab.co/inventory/items" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string" }' ``` --- # Get an inventory item `GET https://api.guidelab.co/inventory/items/{id}` Retrieves the full details of a single inventory item by its ID, including category name. Documentation: https://docs.guidelab.co/api-reference/inventory/getInventoryItem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Inventory item ID ## Responses ### 200: Inventory item details with category name - `data` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `categoryId` (string,null) **(required)**: - `supplierId` (string,null) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `description` (string,null) **(required)**: - `unit` (string) **(required)**: - `currentQuantity` (string) **(required)**: - `minQuantity` (string,null) **(required)**: - `maxQuantity` (string,null) **(required)**: - `unitCost` (string,null) **(required)**: - `currency` (string) **(required)**: - `storageLocation` (string,null) **(required)**: - `lotNumber` (string,null) **(required)**: - `expirationDate` (string,null) **(required)**: - `barcode` (string,null) **(required)**: - `imageKey` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `categoryName` (string,null) **(required)**: ### 401: Unauthorized - valid session required ### 404: Item not found ## Example ```bash curl -X GET "https://api.guidelab.co/inventory/items/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Archive an inventory item `DELETE https://api.guidelab.co/inventory/items/{id}` Soft-deletes an inventory item by marking it as inactive and setting the archived timestamp. The item remains in the database for historical reference. Documentation: https://docs.guidelab.co/api-reference/inventory/archiveInventoryItem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Inventory item ID ## Responses ### 200: Item archived successfully - `success` (boolean) **(required)**: ### 401: Unauthorized - valid session required ### 404: Item not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/inventory/items/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update an inventory item `PUT https://api.guidelab.co/inventory/items/{id}` Updates the metadata of an existing inventory item. Does not change the current quantity - use stock adjustments for that. Documentation: https://docs.guidelab.co/api-reference/inventory/updateInventoryItem ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Inventory item ID ## Request Body Content-Type: `application/json` - `name` (string): - `sku` (string): - `description` (string): - `categoryId` (string): - `supplierId` (string): - `unit` (string): (default: `pcs`) Values: `pcs`, `g`, `kg`, `ml`, `L`, `box`, `roll`, `pack`, `set`, `pair`, `sheet`, `tube`, `bottle`, `cartridge`, `syringe`, `capsule` - `currentQuantity` (object): (default: `0`) - `minQuantity` (object): - `maxQuantity` (object): - `unitCost` (string,null): - `currency` (string): (default: `GBP`) Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `storageLocation` (string): - `lotNumber` (string): - `expirationDate` (string,null): - `barcode` (string): - `notes` (string): ## Responses ### 200: Updated inventory item - `data` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `unit` (string) **(required)**: - `currentQuantity` (string) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 401: Unauthorized - valid session required ### 404: Item not found ### 409: An item with this SKU already exists ## Example ```bash curl -X PUT "https://api.guidelab.co/inventory/items/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Get an inventory item image `GET https://api.guidelab.co/inventory/items/{id}/image` Serves the managed image attached to an inventory item. Documentation: https://docs.guidelab.co/api-reference/inventory/getInventoryItemImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Inventory item image binary ### 404: Item or image not found ## Example ```bash curl -X GET "https://api.guidelab.co/inventory/items/{id}/image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Upload an inventory item image `POST https://api.guidelab.co/inventory/items/{id}/image` Uploads or replaces the managed image for an inventory item. Documentation: https://docs.guidelab.co/api-reference/inventory/uploadInventoryItemImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Inventory item image attached - `imageKey` (string) **(required)**: ### 400: Invalid image ### 404: Item not found ## Example ```bash curl -X POST "https://api.guidelab.co/inventory/items/{id}/image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete an inventory item image `DELETE https://api.guidelab.co/inventory/items/{id}/image` Detaches an inventory item image and queues object deletion. Documentation: https://docs.guidelab.co/api-reference/inventory/deleteInventoryItemImage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Inventory item image removed - `success` (boolean) **(required)**: ### 404: Item or image not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/inventory/items/{id}/image" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List suppliers `GET https://api.guidelab.co/inventory/suppliers` Returns a paginated list of suppliers for the current organization. Supports search by name, code, or email and optional inclusion of inactive suppliers. Documentation: https://docs.guidelab.co/api-reference/inventory/listSuppliers ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `search` (string) (in: query): - `includeInactive` () (in: query): Default: `false` ## Responses ### 200: Paginated list of suppliers - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string,null) **(required)**: - `contactName` (string,null) **(required)**: - `email` (string,null) **(required)**: - `phone` (string,null) **(required)**: - `website` (string,null) **(required)**: - `country` (string) **(required)**: - `currency` (string) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/inventory/suppliers" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a supplier `POST https://api.guidelab.co/inventory/suppliers` Creates a new supplier record for the organization, including contact details, payment terms, and delivery preferences. Documentation: https://docs.guidelab.co/api-reference/inventory/createSupplier ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `code` (string): - `contactName` (string): - `email` (object): - `phone` (string): - `website` (string): - `address` (string): - `addressLine2` (string): - `city` (string): - `postcode` (string): - `country` (string): (default: `GB`) - `paymentTerms` (string): - `leadTimeDays` (integer,null): - `minimumOrderValue` (string,null): - `currency` (string): (default: `GBP`) Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `notes` (string): ## Responses ### 201: Supplier created successfully - `data` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string,null) **(required)**: - `country` (string) **(required)**: - `currency` (string) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 401: Unauthorized - valid session required ### 409: A supplier with this code already exists ## Example ```bash curl -X POST "https://api.guidelab.co/inventory/suppliers" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string" }' ``` --- # Get a supplier `GET https://api.guidelab.co/inventory/suppliers/{id}` Retrieves the full details of a single supplier by its ID. Documentation: https://docs.guidelab.co/api-reference/inventory/getSupplier ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Supplier ID ## Responses ### 200: Supplier details - `data` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string,null) **(required)**: - `contactName` (string,null) **(required)**: - `email` (string,null) **(required)**: - `phone` (string,null) **(required)**: - `website` (string,null) **(required)**: - `country` (string) **(required)**: - `currency` (string) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized - valid session required ### 404: Supplier not found ## Example ```bash curl -X GET "https://api.guidelab.co/inventory/suppliers/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Archive a supplier `DELETE https://api.guidelab.co/inventory/suppliers/{id}` Soft-deletes a supplier by marking it as inactive and setting the archived timestamp. The supplier remains in the database for historical reference. Documentation: https://docs.guidelab.co/api-reference/inventory/archiveSupplier ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Supplier ID ## Responses ### 200: Supplier archived successfully - `success` (boolean) **(required)**: ### 401: Unauthorized - valid session required ### 404: Supplier not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/inventory/suppliers/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a supplier `PUT https://api.guidelab.co/inventory/suppliers/{id}` Updates the details of an existing supplier including contact information, payment terms, and delivery preferences. Documentation: https://docs.guidelab.co/api-reference/inventory/updateSupplier ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Supplier ID ## Request Body Content-Type: `application/json` - `name` (string): - `code` (string): - `contactName` (string): - `email` (object): - `phone` (string): - `website` (string): - `address` (string): - `addressLine2` (string): - `city` (string): - `postcode` (string): - `country` (string): (default: `GB`) - `paymentTerms` (string): - `leadTimeDays` (integer,null): - `minimumOrderValue` (string,null): - `currency` (string): (default: `GBP`) Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `notes` (string): ## Responses ### 200: Updated supplier - `data` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `name` (string) **(required)**: - `code` (string,null) **(required)**: - `country` (string) **(required)**: - `currency` (string) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 401: Unauthorized - valid session required ### 404: Supplier not found ### 409: A supplier with this code already exists ## Example ```bash curl -X PUT "https://api.guidelab.co/inventory/suppliers/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # List stock adjustments `GET https://api.guidelab.co/inventory/adjustments` Returns a paginated list of stock adjustment history for the current organization. Supports filtering by item, reason, and date range. Documentation: https://docs.guidelab.co/api-reference/inventory/listStockAdjustments ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `inventoryItemId` (string) (in: query): - `reason` (string) (in: query): - `source` (string) (in: query): Values: `manual`, `order_consumption`, `order_reversal`, `purchase_receipt`, `system` - `dateFrom` (string) (in: query): - `dateTo` (string) (in: query): - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` ## Responses ### 200: Paginated list of stock adjustments with item and user names - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `inventoryItemId` (string) **(required)**: - `quantityBefore` (string) **(required)**: - `quantityChange` (string) **(required)**: - `quantityAfter` (string) **(required)**: - `source` (string) **(required)**: Values: `manual`, `order_consumption`, `order_reversal`, `purchase_receipt`, `system` - `reason` (string) **(required)**: - `notes` (string,null) **(required)**: - `orderId` (string,null) **(required)**: - `orderItemId` (string,null) **(required)**: - `purchaseOrderId` (string,null) **(required)**: - `purchaseOrderItemId` (string,null) **(required)**: - `purchaseOrderReceiptId` (string,null) **(required)**: - `lotNumber` (string,null) **(required)**: - `expirationDate` (string,null) **(required)**: - `reversesAdjustmentId` (string,null) **(required)**: - `adjustedBy` (string) **(required)**: - `createdAt` (string) **(required)**: - `itemName` (string,null) **(required)**: - `adjustedByName` (string,null) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/inventory/adjustments" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a stock adjustment `POST https://api.guidelab.co/inventory/adjustments` Records a manual stock adjustment for an inventory item. The quantity change can be positive (adding stock) or negative (removing stock). The item's current quantity is updated atomically. Documentation: https://docs.guidelab.co/api-reference/inventory/createStockAdjustment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `inventoryItemId` (string) **(required)**: - `quantityChange` (object) **(required)**: - `reason` (string) **(required)**: - `notes` (string): - `orderId` (string): - `orderItemId` (string): ## Responses ### 201: Stock adjustment recorded and item quantity updated - `data` (object) **(required)**: - `id` (string) **(required)**: - `inventoryItemId` (string) **(required)**: - `organizationId` (string) **(required)**: - `quantityBefore` (string) **(required)**: - `quantityChange` (string) **(required)**: - `quantityAfter` (string) **(required)**: - `source` (string) **(required)**: Values: `manual` - `reason` (string) **(required)**: - `notes` (string,null) **(required)**: - `adjustedBy` (string) **(required)**: - `createdAt` (string) **(required)**: ### 400: Invalid request body or stock cannot go below zero ### 401: Unauthorized - valid session required ### 404: Inventory item not found ## Example ```bash curl -X POST "https://api.guidelab.co/inventory/adjustments" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "inventoryItemId": "string", "quantityChange": "string", "reason": "string", "notes": "string", "orderId": "string", "orderItemId": "string" }' ``` --- # List adjustment reasons `GET https://api.guidelab.co/inventory/adjustment-reasons` Returns all stock adjustment reasons for the current organization, ordered by sort order and label. Optionally includes inactive reasons. Documentation: https://docs.guidelab.co/api-reference/inventory/listAdjustmentReasons ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` (string) (in: query): Set to 'true' to include inactive reasons ## Responses ### 200: List of adjustment reasons - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `key` (string) **(required)**: - `label` (string) **(required)**: - `isSystem` (boolean) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/inventory/adjustment-reasons" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create an adjustment reason `POST https://api.guidelab.co/inventory/adjustment-reasons` Creates a custom stock adjustment reason for the organization. A unique key is auto-generated from the label if not provided. Documentation: https://docs.guidelab.co/api-reference/inventory/createAdjustmentReason ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `label` (string) **(required)**: - `key` (string): ## Responses ### 201: Adjustment reason created successfully - `data` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `key` (string) **(required)**: - `label` (string) **(required)**: - `isSystem` (boolean) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body or could not generate a valid key ### 401: Unauthorized - valid session required ### 409: A reason with this key already exists ## Example ```bash curl -X POST "https://api.guidelab.co/inventory/adjustment-reasons" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "label": "string", "key": "string" }' ``` --- # Reorder adjustment reasons `POST https://api.guidelab.co/inventory/adjustment-reasons/reorder` Updates the sort order of adjustment reasons based on the provided ordered list of reason IDs. All IDs must belong to the current organization. Documentation: https://docs.guidelab.co/api-reference/inventory/reorderAdjustmentReasons ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `reasonIds` (string[]) **(required)**: ## Responses ### 200: Reasons reordered successfully - `success` (boolean) **(required)**: ### 400: Invalid request body ### 401: Unauthorized - valid session required ### 404: One or more reasons not found ## Example ```bash curl -X POST "https://api.guidelab.co/inventory/adjustment-reasons/reorder" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "reasonIds": [ "string" ] }' ``` --- # Seed default adjustment reasons `POST https://api.guidelab.co/inventory/adjustment-reasons/seed` Populates the organization with a default set of stock adjustment reasons (e.g. damaged, expired, manual correction). This is idempotent and will not re-seed if already done. Documentation: https://docs.guidelab.co/api-reference/inventory/seedAdjustmentReasons ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Reasons already seeded - `data` (object) **(required)**: - `alreadySeeded` (boolean): - `seeded` (number): ### 201: Default adjustment reasons seeded successfully - `data` (object) **(required)**: - `seeded` (number) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/inventory/adjustment-reasons/seed" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete an adjustment reason `DELETE https://api.guidelab.co/inventory/adjustment-reasons/{id}` Permanently deletes a custom stock adjustment reason. System-provided reasons cannot be deleted. Documentation: https://docs.guidelab.co/api-reference/inventory/deleteAdjustmentReason ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Reason ID ## Responses ### 200: Reason deleted successfully - `success` (boolean) **(required)**: ### 401: Unauthorized - valid session required ### 403: System reasons cannot be deleted ### 404: Reason not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/inventory/adjustment-reasons/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update an adjustment reason `PUT https://api.guidelab.co/inventory/adjustment-reasons/{id}` Updates the label of an existing stock adjustment reason. Documentation: https://docs.guidelab.co/api-reference/inventory/updateAdjustmentReason ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Reason ID ## Request Body Content-Type: `application/json` - `label` (string) **(required)**: ## Responses ### 200: Updated adjustment reason - `data` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `key` (string) **(required)**: - `label` (string) **(required)**: - `isSystem` (boolean) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 401: Unauthorized - valid session required ### 404: Reason not found ## Example ```bash curl -X PUT "https://api.guidelab.co/inventory/adjustment-reasons/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "label": "string" }' ``` --- # List purchase orders `GET https://api.guidelab.co/inventory/purchase-orders` Returns a paginated list of purchase orders for the current organization. Supports filtering by status and supplier. Documentation: https://docs.guidelab.co/api-reference/inventory/listPurchaseOrders ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `status` (string) (in: query): Values: `draft`, `sent`, `partially_received`, `received`, `cancelled` - `supplierId` (string) (in: query): ## Responses ### 200: Paginated list of purchase orders with supplier names - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `poNumber` (string) **(required)**: - `status` (string) **(required)**: - `supplierId` (string) **(required)**: - `subtotal` (string,null) **(required)**: - `taxAmount` (string,null) **(required)**: - `totalAmount` (string,null) **(required)**: - `currency` (string) **(required)**: - `orderDate` (string,null) **(required)**: - `expectedDeliveryDate` (string,null) **(required)**: - `receivedDate` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `supplierName` (string,null) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/inventory/purchase-orders" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a purchase order `POST https://api.guidelab.co/inventory/purchase-orders` Creates a new purchase order with line items for the specified supplier. Automatically generates a sequential PO number and calculates totals. Documentation: https://docs.guidelab.co/api-reference/inventory/createPurchaseOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `supplierId` (string) **(required)**: - `expectedDeliveryDate` (string): - `notes` (string): - `internalNotes` (string): - `items` (object[]) **(required)**: - `inventoryItemId` (string) **(required)**: - `quantityOrdered` (object) **(required)**: - `unitCost` (string) **(required)**: - `notes` (string): ## Responses ### 201: Purchase order created successfully - `data` (object) **(required)**: - `id` (string) **(required)**: - `poNumber` (string) **(required)**: - `status` (string) **(required)**: - `supplierId` (string) **(required)**: - `subtotal` (string,null) **(required)**: - `totalAmount` (string,null) **(required)**: - `currency` (string) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 401: Unauthorized - valid session required ### 403: Only organization owners or admins can manage purchase orders ### 404: Supplier not found ## Example ```bash curl -X POST "https://api.guidelab.co/inventory/purchase-orders" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "supplierId": "string", "expectedDeliveryDate": "string", "notes": "string", "internalNotes": "string", "items": [ { "inventoryItemId": "string", "quantityOrdered": "string", "unitCost": "string", "notes": "string" } ] }' ``` --- # Get a purchase order `GET https://api.guidelab.co/inventory/purchase-orders/{id}` Retrieves the full details of a purchase order including all line items with their associated inventory item names, SKUs, and units. Documentation: https://docs.guidelab.co/api-reference/inventory/getPurchaseOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Purchase order ID ## Responses ### 200: Purchase order details with line items - `data` (object) **(required)**: - `id` (string) **(required)**: - `poNumber` (string) **(required)**: - `status` (string) **(required)**: - `supplierId` (string) **(required)**: - `subtotal` (string,null) **(required)**: - `taxAmount` (string,null) **(required)**: - `totalAmount` (string,null) **(required)**: - `currency` (string) **(required)**: - `orderDate` (string,null) **(required)**: - `expectedDeliveryDate` (string,null) **(required)**: - `receivedDate` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `internalNotes` (string,null) **(required)**: - `createdBy` (string) **(required)**: - `createdAt` (string) **(required)**: - `supplierName` (string,null) **(required)**: - `items` (object[]) **(required)**: - `id` (string) **(required)**: - `inventoryItemId` (string) **(required)**: - `quantityOrdered` (string) **(required)**: - `quantityReceived` (string) **(required)**: - `unitCost` (string,null) **(required)**: - `totalCost` (string,null) **(required)**: - `notes` (string,null) **(required)**: - `itemName` (string,null) **(required)**: - `itemSku` (string,null) **(required)**: - `itemUnit` (string,null) **(required)**: ### 401: Unauthorized - valid session required ### 404: Purchase order not found ## Example ```bash curl -X GET "https://api.guidelab.co/inventory/purchase-orders/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete a purchase order `DELETE https://api.guidelab.co/inventory/purchase-orders/{id}` Permanently deletes a purchase order. Only draft orders can be deleted; sent or received orders must be cancelled instead. Documentation: https://docs.guidelab.co/api-reference/inventory/deletePurchaseOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Purchase order ID ## Responses ### 200: Purchase order deleted successfully - `success` (boolean) **(required)**: ### 400: Only draft purchase orders can be deleted ### 401: Unauthorized - valid session required ### 403: Only organization owners or admins can manage purchase orders ### 404: Purchase order not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/inventory/purchase-orders/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Send a purchase order `POST https://api.guidelab.co/inventory/purchase-orders/{id}/send` Transitions a draft purchase order to 'sent' status and records the order date. Only draft orders can be sent. Documentation: https://docs.guidelab.co/api-reference/inventory/sendPurchaseOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Purchase order ID ## Responses ### 200: Purchase order marked as sent - `data` (object) **(required)**: - `id` (string) **(required)**: - `poNumber` (string) **(required)**: - `status` (string) **(required)**: - `orderDate` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Only draft orders can be sent ### 401: Unauthorized - valid session required ### 403: Only organization owners or admins can manage purchase orders ### 404: Purchase order not found ## Example ```bash curl -X POST "https://api.guidelab.co/inventory/purchase-orders/{id}/send" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Cancel a purchase order `POST https://api.guidelab.co/inventory/purchase-orders/{id}/cancel` Cancels a purchase order. Cannot cancel orders that are already received or cancelled. Documentation: https://docs.guidelab.co/api-reference/inventory/cancelPurchaseOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Purchase order ID ## Responses ### 200: Purchase order cancelled - `data` (object) **(required)**: - `id` (string) **(required)**: - `poNumber` (string) **(required)**: - `status` (string) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Cannot cancel a received or already cancelled order ### 401: Unauthorized - valid session required ### 403: Only organization owners or admins can manage purchase orders ### 404: Purchase order not found ## Example ```bash curl -X POST "https://api.guidelab.co/inventory/purchase-orders/{id}/cancel" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Receive purchase order items `POST https://api.guidelab.co/inventory/purchase-orders/{id}/receive` Records the receipt of items from a purchase order. Updates inventory quantities, creates stock adjustments, and transitions the PO status to 'partially_received' or 'received' based on whether all items are fully received. Documentation: https://docs.guidelab.co/api-reference/inventory/receivePurchaseOrderItems ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Purchase order ID ## Request Body Content-Type: `application/json` - `commandId` (string) **(required)**: - `items` (object[]) **(required)**: - `purchaseOrderItemId` (string) **(required)**: - `quantityReceived` (object) **(required)**: - `lotNumber` (string): - `expirationDate` (string): ## Responses ### 200: Items received and inventory updated - `data` (object) **(required)**: - `status` (string) **(required)**: ### 400: Only sent or partially received orders can receive items ### 401: Unauthorized - valid session required ### 404: Purchase order not found ### 409: Receipt request is already being processed ### 422: commandId was reused with different receipt parameters ## Example ```bash curl -X POST "https://api.guidelab.co/inventory/purchase-orders/{id}/receive" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "commandId": "string", "items": [ { "purchaseOrderItemId": "string", "quantityReceived": "string", "lotNumber": "string", "expirationDate": "string" } ] }' ``` --- # Get inventory settings `GET https://api.guidelab.co/inventory/settings` Retrieves the user-editable inventory settings for the current organization. Returns sensible defaults if no settings have been configured yet. Documentation: https://docs.guidelab.co/api-reference/inventory/getInventorySettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Inventory settings for the organization - `data` (object) **(required)**: - `lowStockAlertEnabled` (boolean) **(required)**: - `expirationAlertDays` (number) **(required)**: - `autoDeductOnOrderComplete` (boolean) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/inventory/settings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update inventory settings `PUT https://api.guidelab.co/inventory/settings` Creates or updates the inventory module settings for the current organization. Performs an upsert - creates the settings row if it does not exist yet. Documentation: https://docs.guidelab.co/api-reference/inventory/updateInventorySettings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `lowStockAlertEnabled` (boolean): - `expirationAlertDays` (integer): - `autoDeductOnOrderComplete` (boolean): ## Responses ### 200: Updated inventory settings - `data` (object) **(required)**: - `id` (string) **(required)**: - `organizationId` (string) **(required)**: - `lowStockAlertEnabled` (boolean) **(required)**: - `expirationAlertDays` (number) **(required)**: - `autoDeductOnOrderComplete` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 401: Unauthorized - valid session required ## Example ```bash curl -X PUT "https://api.guidelab.co/inventory/settings" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "lowStockAlertEnabled": true, "expirationAlertDays": 0, "autoDeductOnOrderComplete": true }' ``` --- # Get inventory dashboard statistics `GET https://api.guidelab.co/inventory/dashboard/stats` Returns a comprehensive dashboard overview including total item count, total inventory value, low-stock and out-of-stock counts, expiring items, top 10 low-stock items, top 10 expiring items, recent stock adjustments, and category breakdown with values. Documentation: https://docs.guidelab.co/api-reference/inventory/getInventoryDashboardStats ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Inventory dashboard statistics and alerts - `data` (object) **(required)**: - `totalItems` (number) **(required)**: - `totalValue` (string,null) **(required)**: - `lowStockCount` (number) **(required)**: - `outOfStockCount` (number) **(required)**: - `expiringCount` (number) **(required)**: - `expirationAlertDays` (number) **(required)**: - `lowStockItems` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `currentQuantity` (string) **(required)**: - `minQuantity` (string,null) **(required)**: - `unit` (string) **(required)**: - `expiringItems` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `sku` (string,null) **(required)**: - `expirationDate` (string,null) **(required)**: - `currentQuantity` (string) **(required)**: - `unit` (string) **(required)**: - `recentAdjustments` (object[]) **(required)**: - `id` (string) **(required)**: - `inventoryItemId` (string) **(required)**: - `quantityChange` (string) **(required)**: - `source` (string) **(required)**: Values: `manual`, `order_consumption`, `order_reversal`, `purchase_receipt`, `system` - `reason` (string) **(required)**: - `notes` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `itemName` (string,null) **(required)**: - `adjustedByName` (string,null) **(required)**: - `categoryBreakdown` (object[]) **(required)**: - `categoryId` (string,null) **(required)**: - `categoryName` (string,null) **(required)**: - `categoryDescription` (string,null) **(required)**: - `categoryIcon` (string,null) **(required)**: - `itemCount` (number) **(required)**: - `totalValue` (string,null) **(required)**: ### 401: Unauthorized - valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/inventory/dashboard/stats" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Start Stripe Connect O Auth `POST https://api.guidelab.co/stripe-connect/oauth/start` Start a one-time Stripe Standard OAuth flow. The lab owner can sign into an existing Stripe account or create a new one on Stripe. Documentation: https://docs.guidelab.co/api-reference/stripe-connect/startStripeConnectOAuth ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `returnUrl` (string): ## Responses ### 200: Stripe Standard OAuth authorization URL - `url` (string) **(required)**: [uri] - `accountId` (string,null) **(required)**: - `flow` (string) **(required)**: Values: `oauth` ### 409: The lab already has an active Stripe connection ### 500: Stripe Connect OAuth is not configured ### 503: Stripe environment is not configured safely ## Example ```bash curl -X POST "https://api.guidelab.co/stripe-connect/oauth/start" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "returnUrl": "string" }' ``` --- # Onboard Stripe Connect `POST https://api.guidelab.co/stripe-connect/onboard` Compatibility alias for the Stripe Standard OAuth start command. No account is created until the user selects or creates one on Stripe. Documentation: https://docs.guidelab.co/api-reference/stripe-connect/onboardStripeConnect ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `returnUrl` (string): ## Responses ### 200: Stripe Standard OAuth authorization URL - `url` (string) **(required)**: [uri] - `accountId` (string,null) **(required)**: - `flow` (string) **(required)**: Values: `oauth` ### 409: The lab already has an active Stripe connection ### 500: Stripe Connect OAuth is not configured ### 503: Stripe environment is not configured safely ## Example ```bash curl -X POST "https://api.guidelab.co/stripe-connect/onboard" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "returnUrl": "string" }' ``` --- # Handle Stripe Connect O Auth Callback `GET https://api.guidelab.co/stripe-connect/oauth/callback` Consume a lab-owner-bound OAuth state, exchange Stripe's one-time code, retain the connection generation, reconcile account requirements, and redirect safely to the app. Documentation: https://docs.guidelab.co/api-reference/stripe-connect/handleStripeConnectOAuthCallback ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `code` (string) (in: query): - `state` (string) (in: query): - `error` (string) (in: query): - `error_description` (string) (in: query): ## Responses ### 302: Redirect to the same-origin lab finance settings view ### 401: The initiating user session is unavailable ## Example ```bash curl -X GET "https://api.guidelab.co/stripe-connect/oauth/callback" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Stripe Connect Status `GET https://api.guidelab.co/stripe-connect/status` Return the cached active Stripe connection and its latest requirements snapshot without contacting Stripe. Documentation: https://docs.guidelab.co/api-reference/stripe-connect/getStripeConnectStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Cached Stripe Connect status - `connected` (boolean) **(required)**: - `connectionId` (string,null) **(required)**: - `accountId` (string,null) **(required)**: - `accountType` (string,null) **(required)**: Values: `standard`, `express`, `custom`, `null` - `chargesEnabled` (boolean) **(required)**: - `payoutsEnabled` (boolean) **(required)**: - `onboardingComplete` (boolean) **(required)**: - `detailsSubmitted` (boolean) **(required)**: - `email` (string,null) **(required)**: - `businessName` (string,null) **(required)**: - `country` (string,null) **(required)**: - `requirements` (object) **(required)**: - `currentlyDue` (string[]) **(required)**: - `eventuallyDue` (string[]) **(required)**: - `pastDue` (string[]) **(required)**: - `pendingVerification` (string[]) **(required)**: - `disabledReason` (string,null) **(required)**: - `currentDeadline` (string,null) **(required)**: [date-time] - `connectedAt` (string,null) **(required)**: [date-time] - `lastProviderEventId` (string,null) **(required)**: - `lastProviderEventAt` (string,null) **(required)**: [date-time] ## Example ```bash curl -X GET "https://api.guidelab.co/stripe-connect/status" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Refresh Stripe Connect Status `POST https://api.guidelab.co/stripe-connect/status/refresh` Retrieve the active account from Stripe and reconcile its capabilities, onboarding state, and requirements snapshot. Documentation: https://docs.guidelab.co/api-reference/stripe-connect/refreshStripeConnectStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Reconciled Stripe Connect status - `connected` (boolean) **(required)**: - `connectionId` (string,null) **(required)**: - `accountId` (string,null) **(required)**: - `accountType` (string,null) **(required)**: Values: `standard`, `express`, `custom`, `null` - `chargesEnabled` (boolean) **(required)**: - `payoutsEnabled` (boolean) **(required)**: - `onboardingComplete` (boolean) **(required)**: - `detailsSubmitted` (boolean) **(required)**: - `email` (string,null) **(required)**: - `businessName` (string,null) **(required)**: - `country` (string,null) **(required)**: - `requirements` (object) **(required)**: - `currentlyDue` (string[]) **(required)**: - `eventuallyDue` (string[]) **(required)**: - `pastDue` (string[]) **(required)**: - `pendingVerification` (string[]) **(required)**: - `disabledReason` (string,null) **(required)**: - `currentDeadline` (string,null) **(required)**: [date-time] - `connectedAt` (string,null) **(required)**: [date-time] - `lastProviderEventId` (string,null) **(required)**: - `lastProviderEventAt` (string,null) **(required)**: [date-time] ### 500: Stripe is not configured ### 502: Stripe account status is temporarily unavailable ### 503: Stripe environment is not configured safely ## Example ```bash curl -X POST "https://api.guidelab.co/stripe-connect/status/refresh" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Stripe Connect Dashboard Link `GET https://api.guidelab.co/stripe-connect/dashboard-link` Return the Stripe Dashboard URL for Standard accounts, with legacy login-link support for Express accounts. Documentation: https://docs.guidelab.co/api-reference/stripe-connect/getStripeConnectDashboardLink ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Stripe Dashboard URL and account type - `url` (string) **(required)**: [uri] - `type` (string) **(required)**: ### 400: No Stripe account is connected ### 502: Stripe Dashboard is temporarily unavailable ## Example ```bash curl -X GET "https://api.guidelab.co/stripe-connect/dashboard-link" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Disconnect Stripe Connect `POST https://api.guidelab.co/stripe-connect/disconnect` Revoke the Standard OAuth authorization and deactivate the current local connection while retaining its account and lifecycle history. Documentation: https://docs.guidelab.co/api-reference/stripe-connect/disconnectStripeConnect ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Stripe account disconnected - `success` (boolean) **(required)**: Values: `true` - `message` (string) **(required)**: ### 400: No Stripe account is connected ### 409: Disconnect is blocked while payment, autopay, or refund commands are unsettled - `error` (string) **(required)**: - `blockers` (string[]) **(required)**: ### 500: Stripe Connect OAuth is not configured ### 502: Stripe rejected the disconnection ### 503: Stripe environment is not configured safely ## Example ```bash curl -X POST "https://api.guidelab.co/stripe-connect/disconnect" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get Checkout Payment Status `POST https://api.guidelab.co/checkout/payment-status` Resume a clinic's retained payment claim. One bounded Stripe read for an unsettled claim; never creates or confirms a payment. Documentation: https://docs.guidelab.co/api-reference/checkout/getCheckoutPaymentStatus ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `labId` (string) **(required)**: - `paymentIntentId` (string) **(required)**: - `purpose` (string) **(required)**: Values: `order_payment`, `invoice_payment` - `draftOrderId` (string): ## Responses ### 200: Authoritative settlement or provider processing state - `providerStatus` (string): - `orderAutopayEnabled` (boolean): - `clientSecret` (string,null) **(required)**: - `customerSessionClientSecret` (string,null) **(required)**: - `customerId` (string,null): - `paymentIntentId` (string) **(required)**: - `amount` (number) **(required)**: - `amountDisplay` (string) **(required)**: - `pricing` (object,null) **(required)**: - `subtotal` (string) **(required)**: - `discountPercent` (string) **(required)**: - `discountAmount` (string) **(required)**: - `taxMode` (string) **(required)**: Values: `none`, `exclusive`, `inclusive` - `taxAmount` (string) **(required)**: - `stampDutyAmount` (string) **(required)**: - `shippingAmount` (string) **(required)**: - `totalAmount` (string) **(required)**: - `payLaterTotal` (string) **(required)**: - `currency` (string) **(required)**: - `status` (string) **(required)**: - `convertedOrderId` (string,null) **(required)**: - `taxAmount` (string,null) **(required)**: - `taxMode` (string,null) **(required)**: Values: `none`, `exclusive`, `inclusive`, `null` - `taxIncludedInPrices` (boolean,null) **(required)**: - `state` (string) **(required)**: Values: `succeeded`, `pending`, `retryable`, `canceled` - `stripeAccountId` (string) **(required)**: ### 403: Payment ownership or role mismatch ### 404: Retained payment not found ### 429: Status read budget exhausted ## Example ```bash curl -X POST "https://api.guidelab.co/checkout/payment-status" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "labId": "string", "paymentIntentId": "string", "purpose": "order_payment", "draftOrderId": "string" }' ``` --- # Create Payment Intent `POST https://api.guidelab.co/checkout/create-payment-intent` Create a Stripe PaymentIntent for the authenticated clinic to pay invoices or an order basket. Clinic-only. Prices are resolved from the lab catalog. Documentation: https://docs.guidelab.co/api-reference/checkout/createPaymentIntent ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `labId` (string) **(required)**: Lab ID to pay - `idempotencyKey` (string) **(required)**: Stable key for this payment attempt; reuse it only for an exact retry - `invoiceIds` (string[]): - `items` (object[]): - `productId` (string) **(required)**: - `toothGroups` (object[]): - `id` (string) **(required)**: - `type` (string) **(required)**: Values: `single`, `bridge` - `teeth` (object[]) **(required)**: - `fdi` (integer) **(required)**: - `role` (string) **(required)**: Values: `crown`, `pontic` - `support` (string): Values: `natural`, `implant` - `implantSystemId` (string): - `implantPlatform` (string): - `quantity` (integer): (default: `1`) - `materialId` (string): - `material` (string): - `shadeSystemId` (string): - `shadeOcclusal` (string): - `shadeMiddle` (string): - `shadeGingival` (string): - `shadeNotes` (string): - `defaultImplantSystemId` (string): - `defaultImplantPlatform` (string): - `notes` (string): - `customFieldValues` (object): - `value` (object): - `fileIds` (string[]): - `bundleId` (string): - `bundleInstanceId` (string): - `draftOrderId` (string): - `enableOrderAutopay` (boolean): ## Responses ### 200: PaymentIntent created with client secret for Stripe.js confirmation - `providerStatus` (string): - `orderAutopayEnabled` (boolean): - `clientSecret` (string,null) **(required)**: - `customerSessionClientSecret` (string,null) **(required)**: - `customerId` (string,null): - `paymentIntentId` (string) **(required)**: - `amount` (number) **(required)**: - `amountDisplay` (string) **(required)**: - `pricing` (object,null) **(required)**: - `subtotal` (string) **(required)**: - `discountPercent` (string) **(required)**: - `discountAmount` (string) **(required)**: - `taxMode` (string) **(required)**: Values: `none`, `exclusive`, `inclusive` - `taxAmount` (string) **(required)**: - `stampDutyAmount` (string) **(required)**: - `shippingAmount` (string) **(required)**: - `totalAmount` (string) **(required)**: - `payLaterTotal` (string) **(required)**: - `currency` (string) **(required)**: - `status` (string) **(required)**: - `convertedOrderId` (string,null) **(required)**: - `taxAmount` (string,null) **(required)**: - `taxMode` (string,null) **(required)**: Values: `none`, `exclusive`, `inclusive`, `null` - `taxIncludedInPrices` (boolean,null) **(required)**: ### 400: Invalid request, invoices not payable, or lab has not connected Stripe - `error` (string) **(required)**: - `code` (string): Values: `stripe_not_connected`, `lab_subscription_inactive`, `tax_policy_unconfigured`, `draft_not_found`, `draft_not_payable`, `partnership_inactive`, `payment_not_required`, `payment_required`, `draft_changed`, `catalog_unavailable`, `due_date_invalid`, `surgery_date_required`, `surgery_date_invalid`, `total_not_positive`, `retry_required`, `unavailable`, `shipping_changed`, `issue_remake_unavailable` - `details` (object): - `code` (string) **(required)**: Values: `payment_amount_exceeds_provider_limit` - `maxMinor` (string) **(required)**: Values: `99999999` - `currency` (string) **(required)**: ### 402: Destination lab has no active subscription - `error` (string) **(required)**: - `code` (string): Values: `stripe_not_connected`, `lab_subscription_inactive`, `tax_policy_unconfigured`, `draft_not_found`, `draft_not_payable`, `partnership_inactive`, `payment_not_required`, `payment_required`, `draft_changed`, `catalog_unavailable`, `due_date_invalid`, `surgery_date_required`, `surgery_date_invalid`, `total_not_positive`, `retry_required`, `unavailable`, `shipping_changed`, `issue_remake_unavailable` ### 409: Payment attempt conflicts with an existing claim. `details.code` PAYMENT_ATTEMPT_RETRY_REQUIRED means retry with a new idempotency key; a `catalog_unavailable` refusal lists the offending `details.productIds`. - `error` (string) **(required)**: - `code` (string): Values: `stripe_not_connected`, `lab_subscription_inactive`, `tax_policy_unconfigured`, `draft_not_found`, `draft_not_payable`, `partnership_inactive`, `payment_not_required`, `payment_required`, `draft_changed`, `catalog_unavailable`, `due_date_invalid`, `surgery_date_required`, `surgery_date_invalid`, `total_not_positive`, `retry_required`, `unavailable`, `shipping_changed`, `issue_remake_unavailable` - `details` (object): ### 500: Stripe secret key not configured ## Example ```bash curl -X POST "https://api.guidelab.co/checkout/create-payment-intent" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "labId": "string", "idempotencyKey": "string", "invoiceIds": [ "string" ], "items": [ { "productId": "string" } ], "draftOrderId": "string", "enableOrderAutopay": true }' ``` --- # Confirm Checkout Payment `POST https://api.guidelab.co/checkout/confirm-order` Verify that a Stripe PaymentIntent has succeeded after the client-side payment flow completes. Clinic-only. Used as a server-side confirmation step before updating order/invoice status. Documentation: https://docs.guidelab.co/api-reference/checkout/confirmCheckoutPayment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `paymentIntentId` (string) **(required)**: Stripe PaymentIntent ID to verify - `labId` (string) **(required)**: Lab ID the payment was made to ## Responses ### 200: Payment verified successfully with amount and currency details - `verified` (boolean) **(required)**: - `paymentIntentId` (string) **(required)**: - `amount` (number) **(required)**: - `currency` (string) **(required)**: - `convertedOrderId` (string) **(required)**: ### 400: Payment not completed, missing parameters, or lab not connected to Stripe ### 500: Stripe secret key not configured ## Example ```bash curl -X POST "https://api.guidelab.co/checkout/confirm-order" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "paymentIntentId": "string", "labId": "string" }' ``` --- # Cancel Checkout Order Payment `POST https://api.guidelab.co/checkout/cancel-order-payment` Cancel or reconcile the authenticated clinic's active upfront order payment before unlocking its prepared draft. Documentation: https://docs.guidelab.co/api-reference/checkout/cancelCheckoutOrderPayment ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `labId` (string) **(required)**: - `draftOrderId` (string) **(required)**: ## Responses ### 200: Payment canceled or reconciled - `unlocked` (boolean) **(required)**: - `convertedOrderId` (string,null) **(required)**: - `paymentIntentId` (string,null) **(required)**: ### 409: Payment is already final or cannot be canceled safely ### 500: Stripe secret key not configured ## Example ```bash curl -X POST "https://api.guidelab.co/checkout/cancel-order-payment" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "labId": "string", "draftOrderId": "string" }' ``` --- # List Clinic Payment Methods `GET https://api.guidelab.co/clinic-payment-methods` List saved payment methods for the authenticated clinic with a specific lab. Clinic-owner only. Requires labId query parameter to identify the lab's Stripe Connect account. Documentation: https://docs.guidelab.co/api-reference/clinic-payment-methods/listClinicPaymentMethods ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `labId` (string) **(required)** (in: query): Lab ID to retrieve payment methods for ## Responses ### 200: List of saved payment methods with card details and default status - `paymentMethods` (object[]) **(required)**: - `id` (string) **(required)**: - `type` (string) **(required)**: - `brand` (string,null) **(required)**: - `last4` (string,null) **(required)**: - `expMonth` (number,null) **(required)**: - `expYear` (number,null) **(required)**: - `isDefault` (boolean) **(required)**: ### 400: Missing labId parameter - `error` (string) **(required)**: ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/clinic-payment-methods" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Delete Clinic Payment Method `DELETE https://api.guidelab.co/clinic-payment-methods/{id}` Detach and remove a saved payment method from the authenticated clinic's Stripe customer. Clinic-owner only. Requires labId query parameter. Documentation: https://docs.guidelab.co/api-reference/clinic-payment-methods/deleteClinicPaymentMethod ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Stripe payment method ID to detach - `labId` (string) **(required)** (in: query): Lab ID the payment method belongs to ## Responses ### 200: Payment method detached successfully - `success` (boolean) **(required)**: ### 400: Missing labId or lab has not connected Stripe - `error` (string) **(required)**: ### 404: Customer, partnership, or payment method not found ### 409: Payment method is used by active autopay or the Stripe connection changed ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/clinic-payment-methods/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Set Default Clinic Payment Method `PUT https://api.guidelab.co/clinic-payment-methods/{id}` Set a saved payment method as the default for the authenticated clinic with a specific lab. Clinic-owner only. Documentation: https://docs.guidelab.co/api-reference/clinic-payment-methods/setDefaultClinicPaymentMethod ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Stripe payment method ID ## Request Body Content-Type: `application/json` - `labId` (string) **(required)**: Lab ID the payment method belongs to ## Responses ### 200: Payment method set as default successfully - `success` (boolean) **(required)**: ### 400: Missing labId or lab has not connected Stripe - `error` (string) **(required)**: ### 404: No Stripe customer mapping found for this clinic-lab pair - `error` (string) **(required)**: ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/clinic-payment-methods/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "labId": "string" }' ``` --- # Create Clinic Setup Intent `POST https://api.guidelab.co/clinic-payment-methods/setup-intent` Create a Stripe SetupIntent to save a new payment method for the authenticated clinic with a specific lab. Clinic-owner only. Automatically creates a Stripe customer if one does not exist. Documentation: https://docs.guidelab.co/api-reference/clinic-payment-methods/createClinicSetupIntent ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `labId` (string) **(required)**: Lab ID to create the setup intent for ## Responses ### 200: Setup intent created with client secret for Stripe.js confirmation - `clientSecret` (string,null) **(required)**: - `stripeAccountId` (string) **(required)**: ### 400: Missing labId or lab has not connected Stripe - `error` (string) **(required)**: ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/clinic-payment-methods/setup-intent" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "labId": "string" }' ``` --- # Get clinic autopay consent `GET https://api.guidelab.co/clinic-payment-methods/autopay/{partnershipId}` Returns the clinic-owned saved-card autopay state for a partnership. Both partnership parties may read it; labs cannot mutate it. Documentation: https://docs.guidelab.co/api-reference/clinic-payment-methods/getClinicAutopayMandate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `partnershipId` (string) **(required)** (in: path): ## Responses ### 200: Autopay mandate state - `enabled` (boolean) **(required)**: - `status` (string,null) **(required)**: Values: `active`, `suspended`, `revoked`, `null` - `consentedAt` (string,null) **(required)**: [date-time] - `revokedAt` (string,null) **(required)**: [date-time] - `suspendedAt` (string,null) **(required)**: [date-time] ### 404: Partnership not found ## Example ```bash curl -X GET "https://api.guidelab.co/clinic-payment-methods/autopay/{partnershipId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Revoke clinic-owned autopay `DELETE https://api.guidelab.co/clinic-payment-methods/autopay/{partnershipId}` Revokes future off-session charges for this partnership. Only a clinic owner can perform this operation; labs have read-only visibility. Documentation: https://docs.guidelab.co/api-reference/clinic-payment-methods/revokeClinicAutopayMandate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `partnershipId` (string) **(required)** (in: path): ## Responses ### 200: Autopay revoked - `enabled` (boolean) **(required)**: - `status` (string,null) **(required)**: Values: `active`, `suspended`, `revoked`, `null` - `consentedAt` (string,null) **(required)**: [date-time] - `revokedAt` (string,null) **(required)**: [date-time] - `suspendedAt` (string,null) **(required)**: [date-time] ### 404: Partnership not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/clinic-payment-methods/autopay/{partnershipId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Enable clinic-owned saved-card autopay `POST https://api.guidelab.co/clinic-payment-methods/autopay` Lets a clinic owner consent to off-session card charges for one active lab partnership. The selected card must already belong to that lab's connected Stripe customer. Documentation: https://docs.guidelab.co/api-reference/clinic-payment-methods/enableClinicAutopayMandate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `partnershipId` (string) **(required)**: - `paymentMethodId` (string) **(required)**: ## Responses ### 200: Autopay enabled - `enabled` (boolean) **(required)**: - `status` (string,null) **(required)**: Values: `active`, `suspended`, `revoked`, `null` - `consentedAt` (string,null) **(required)**: [date-time] - `revokedAt` (string,null) **(required)**: [date-time] - `suspendedAt` (string,null) **(required)**: [date-time] ### 400: Stripe is unavailable for this partnership ### 404: Partnership, customer, or card not found ### 409: The lab's connected account changed ### 500: Stripe is not configured ## Example ```bash curl -X POST "https://api.guidelab.co/clinic-payment-methods/autopay" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "partnershipId": "string", "paymentMethodId": "string" }' ``` --- # Get lab dashboard statistics `GET https://api.guidelab.co/dashboard/stats` Returns monthly order counts, revenue totals, completion rates, and deadline breakdown for the authenticated lab. Compares current month to previous month for trend calculation. Documentation: https://docs.guidelab.co/api-reference/dashboard/getLabDashboardStats ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Monthly stats, trends, and deadline counts - `monthly` (object) **(required)**: - `totalOrders` (number) **(required)**: - `completedOrders` (number) **(required)**: - `pendingOrders` (number) **(required)**: - `currency` (string) **(required)**: Currency scope of the legacy monetary fields; order counts include every currency. Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `revenue` (number) **(required)**: Compatibility projection of revenueExact for the lab currency. - `revenueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `avgOrderValue` (number) **(required)**: Compatibility projection of avgOrderValueExact for the lab currency. - `avgOrderValueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `currencyTotals` (object[]) **(required)**: - `currency` (string) **(required)**: Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `totalOrders` (number) **(required)**: - `completedOrders` (number) **(required)**: - `pendingOrders` (number) **(required)**: - `revenueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `previousRevenueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `avgOrderValueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `trends` (object) **(required)**: - `orders` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `completed` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `revenue` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `pending` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `trends` (object) **(required)**: - `orders` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `completed` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `revenue` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `pending` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `deadlines` (object) **(required)**: - `overdue` (number) **(required)**: - `today` (number) **(required)**: - `tomorrow` (number) **(required)**: - `thisWeek` (number) **(required)**: ### 401: Unauthorized — valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/dashboard/stats" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get today's hourly breakdown `GET https://api.guidelab.co/dashboard/today` Returns hourly order or revenue data for a given day (defaults to today). Includes cumulative totals and end-of-day projection. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/dashboard/getLabDashboardToday ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Hourly data points with cumulative totals and projection - `date` (string) **(required)**: - `metric` (string) **(required)**: Values: `orders`, `revenue` - `currency` (string,null) **(required)**: Currency of the numeric compatibility projection; null for the orders metric. Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR`, `null` - `dataPoints` (object[]) **(required)**: - `hour` (number) **(required)**: - `value` (number) **(required)**: - `cumulative` (number) **(required)**: - `valueExact` (string,null) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `cumulativeExact` (string,null) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `currencySeries` (object[]) **(required)**: - `currency` (string) **(required)**: Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `dataPoints` (object[]) **(required)**: - `hour` (number) **(required)**: - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `cumulativeExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `summary` (object) **(required)**: - `currentValueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `currentTime` (string) **(required)**: - `projectedEndOfDayExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `summary` (object) **(required)**: - `currentValue` (number) **(required)**: - `currentValueExact` (string,null) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `currentTime` (string) **(required)**: - `projectedEndOfDay` (number) **(required)**: - `projectedEndOfDayExact` (string,null) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) ### 401: Unauthorized — valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/dashboard/today" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get order and revenue trends `GET https://api.guidelab.co/dashboard/trends` Returns daily submitted and completed order counts and revenue over a date range (defaults to last 30 days). Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/dashboard/getLabDashboardTrends ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Daily series for submitted/completed orders with totals - `dateRange` (object) **(required)**: - `start` (string) **(required)**: - `end` (string) **(required)**: - `currency` (string) **(required)**: Currency scope of the legacy monetary fields; order counts include every currency. Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `series` (object) **(required)**: - `submitted` (object[]) **(required)**: - `date` (string) **(required)**: - `count` (number) **(required)**: - `value` (number) **(required)**: Compatibility projection of valueExact for the lab currency. - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `completed` (object[]) **(required)**: - `date` (string) **(required)**: - `count` (number) **(required)**: - `value` (number) **(required)**: Compatibility projection of valueExact for the lab currency. - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `currencySeries` (object[]) **(required)**: - `currency` (string) **(required)**: Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `series` (object) **(required)**: - `submitted` (object[]) **(required)**: - `date` (string) **(required)**: - `count` (number) **(required)**: - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `completed` (object[]) **(required)**: - `date` (string) **(required)**: - `count` (number) **(required)**: - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `totals` (object) **(required)**: - `submitted` (object) **(required)**: - `count` (number) **(required)**: - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `completed` (object) **(required)**: - `count` (number) **(required)**: - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `totals` (object) **(required)**: - `submitted` (object) **(required)**: - `count` (number) **(required)**: - `value` (number) **(required)**: - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `completed` (object) **(required)**: - `count` (number) **(required)**: - `value` (number) **(required)**: - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) ### 401: Unauthorized — valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/dashboard/trends" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get active orders by deadline `GET https://api.guidelab.co/dashboard/operations` Lists active orders filtered by deadline urgency (overdue, today, tomorrow, or all). Returns paginated results with patient, clinic, and category info. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/dashboard/getLabDashboardOperations ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `deadline` (string) (in: query): Values: `overdue`, `today`, `tomorrow`, `all` Default: `all` - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `20` - `status` (string) (in: query): ## Responses ### 200: Paginated list of active orders with deadline info - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `patient` (object,null) **(required)**: - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: - `status` (string) **(required)**: - `practice` (object,null) **(required)**: - `name` (string) **(required)**: - `doctor` (string,null) **(required)**: - `category` (string,null) **(required)**: - `dueDate` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 401: Unauthorized — valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/dashboard/operations" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List orders currently blocked by an active hold `GET https://api.guidelab.co/dashboard/blocked-orders` Returns a bounded cursor page of on-hold orders for the authenticated lab. Patient names honor the order's lab-masking policy. Documentation: https://docs.guidelab.co/api-reference/dashboard/getLabDashboardBlockedOrders ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `severity` (string) (in: query): Values: `critical`, `high`, `medium` - `cursor` (string) (in: query): - `limit` (integer) (in: query): Default: `10` ## Responses ### 200: Blocked orders, most severe first, then longest blocked first - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `holdId` (string) **(required)**: - `holdReasonName` (string) **(required)**: - `holdSummary` (object,null) **(required)**: - `kind` (string) **(required)**: Values: `surgical_report`, `cad_approval`, `file_reupload`, `manual` - `awaiting` (string) **(required)**: Values: `lab`, `clinic` - `reasonName` (string) **(required)**: - `blockedAt` (string) **(required)**: - `blockedHours` (integer) **(required)**: - `overdueDays` (integer) **(required)**: - `severity` (string) **(required)**: Values: `critical`, `high`, `medium` - `deadline` (string,null) **(required)**: - `patientName` (string,null) **(required)**: - `practiceName` (string,null) **(required)**: - `deepLink` (string) **(required)**: - `counts` (object) **(required)**: - `all` (integer) **(required)**: - `critical` (integer) **(required)**: - `high` (integer) **(required)**: - `medium` (integer) **(required)**: - `nextCursor` (string,null) **(required)**: ### 400: Invalid cursor or query ### 401: Unauthorized ### 403: Only labs can list blocked orders ## Example ```bash curl -X GET "https://api.guidelab.co/dashboard/blocked-orders" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get exact clinic dashboard counters `GET https://api.guidelab.co/dashboard/clinic/stats` Returns tenant-scoped aggregate counters without loading or returning patient rows. Documentation: https://docs.guidelab.co/api-reference/dashboard/getClinicDashboardStats ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Clinic dashboard counters - `actionsRequired` (integer) **(required)**: - `awaitingApproval` (integer) **(required)**: - `activeOrders` (integer) **(required)**: - `deliveriesToday` (integer) **(required)**: - `invoicesToPay` (integer) **(required)**: - `unreadMessages` (integer) **(required)**: - `upcomingShipments` (integer) **(required)**: ### 401: Unauthorized ### 403: Only clinics can read clinic dashboard stats ## Example ```bash curl -X GET "https://api.guidelab.co/dashboard/clinic/stats" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List clinic actions `GET https://api.guidelab.co/dashboard/clinic/actions` Returns a bounded, cursor-paginated union of current clinic actions. Deep links are derived from trusted source rows. Documentation: https://docs.guidelab.co/api-reference/dashboard/getClinicDashboardActions ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `cursor` (string) (in: query): - `limit` (integer) (in: query): Default: `6` ## Responses ### 200: Clinic action page - `data` (object[]) **(required)**: - `sourceKind` (string) **(required)**: - `sourceId` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string) **(required)**: - `actionType` (string) **(required)**: Values: `approve_surgical_report`, `approve_cad_design`, `upload_phase_files`, `reupload_requested_files` - `priority` (string) **(required)**: Values: `high`, `medium`, `low` - `dueAt` (string,null) **(required)**: - `createdAt` (string) **(required)**: - `deepLink` (string) **(required)**: - `patientName` (string,null) **(required)**: - `doctorName` (string,null) **(required)**: - `labName` (string,null) **(required)**: - `phaseId` (string,null) **(required)**: - `phaseName` (string,null) **(required)**: - `products` (string,null) **(required)**: - `submittedAt` (string,null) **(required)**: - `orderDueDate` (string,null) **(required)**: - `phaseSummary` (object): - `phases` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `sortOrder` (number) **(required)**: - `currentPhaseTaskId` (string,null) **(required)**: - `filesSubmitted` (boolean) **(required)**: - `plannedDate` (string,null) **(required)**: - `color` (string,null): - `productNames` (string[]): - `tasks` (object[]) **(required)**: - `id` (string) **(required)**: - `taskId` (string) **(required)**: - `label` (string) **(required)**: - `sortOrder` (number) **(required)**: - `color` (string,null): - `icon` (string,null): - `isDone` (boolean) **(required)**: - `completedAt` (string,null): - `nextCursor` (string,null) **(required)**: ### 400: Invalid cursor or query ### 401: Unauthorized ### 403: Only clinics can list clinic actions ## Example ```bash curl -X GET "https://api.guidelab.co/dashboard/clinic/actions" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List clinic-safe recent order activity `GET https://api.guidelab.co/dashboard/clinic/activity` Returns only safe event classifications and order references. Raw activity payloads, notes, attachment IDs, and lab-internal task events are never selected. Documentation: https://docs.guidelab.co/api-reference/dashboard/getClinicDashboardActivity ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `cursor` (string) (in: query): - `limit` (integer) (in: query): Default: `4` ## Responses ### 200: Clinic activity page - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `orderId` (string) **(required)**: - `orderNumber` (string) **(required)**: - `eventType` (string) **(required)**: Values: `status_changed`, `phase_changed`, `file_uploaded`, `task_review_event` - `summaryKey` (string) **(required)**: - `createdAt` (string) **(required)**: - `deepLink` (string) **(required)**: - `nextCursor` (string,null) **(required)**: ### 400: Invalid cursor or query ### 401: Unauthorized ### 403: Only clinics can list clinic activity ## Example ```bash curl -X GET "https://api.guidelab.co/dashboard/clinic/activity" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Bootstrap all lab dashboard panels in one call `GET https://api.guidelab.co/dashboard/overview` Aggregates /dashboard/stats, /dashboard/today, /dashboard/trends, and /dashboard/operations into a single parallel request. Defaults: today's date, revenue metric, 30-day trends, all deadlines, page 1, limit 10. Documentation: https://docs.guidelab.co/api-reference/dashboard/getLabDashboardOverview ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Combined stats, today, trends, and operations payload - `stats` (object) **(required)**: - `monthly` (object) **(required)**: - `totalOrders` (number) **(required)**: - `completedOrders` (number) **(required)**: - `pendingOrders` (number) **(required)**: - `currency` (string) **(required)**: Currency scope of the legacy monetary fields; order counts include every currency. Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `revenue` (number) **(required)**: Compatibility projection of revenueExact for the lab currency. - `revenueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `avgOrderValue` (number) **(required)**: Compatibility projection of avgOrderValueExact for the lab currency. - `avgOrderValueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `currencyTotals` (object[]) **(required)**: - `currency` (string) **(required)**: Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `totalOrders` (number) **(required)**: - `completedOrders` (number) **(required)**: - `pendingOrders` (number) **(required)**: - `revenueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `previousRevenueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `avgOrderValueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `trends` (object) **(required)**: - `orders` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `completed` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `revenue` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `pending` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `trends` (object) **(required)**: - `orders` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `completed` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `revenue` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `pending` (object) **(required)**: - `change` (string) **(required)**: - `type` (string) **(required)**: Values: `increase`, `decrease`, `neutral` - `deadlines` (object) **(required)**: - `overdue` (number) **(required)**: - `today` (number) **(required)**: - `tomorrow` (number) **(required)**: - `thisWeek` (number) **(required)**: - `today` (object) **(required)**: - `date` (string) **(required)**: - `metric` (string) **(required)**: Values: `orders`, `revenue` - `currency` (string,null) **(required)**: Currency of the numeric compatibility projection; null for the orders metric. Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR`, `null` - `dataPoints` (object[]) **(required)**: - `hour` (number) **(required)**: - `value` (number) **(required)**: - `cumulative` (number) **(required)**: - `valueExact` (string,null) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `cumulativeExact` (string,null) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `currencySeries` (object[]) **(required)**: - `currency` (string) **(required)**: Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `dataPoints` (object[]) **(required)**: - `hour` (number) **(required)**: - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `cumulativeExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `summary` (object) **(required)**: - `currentValueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `currentTime` (string) **(required)**: - `projectedEndOfDayExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `summary` (object) **(required)**: - `currentValue` (number) **(required)**: - `currentValueExact` (string,null) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `currentTime` (string) **(required)**: - `projectedEndOfDay` (number) **(required)**: - `projectedEndOfDayExact` (string,null) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `trends` (object) **(required)**: - `dateRange` (object) **(required)**: - `start` (string) **(required)**: - `end` (string) **(required)**: - `currency` (string) **(required)**: Currency scope of the legacy monetary fields; order counts include every currency. Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `series` (object) **(required)**: - `submitted` (object[]) **(required)**: - `date` (string) **(required)**: - `count` (number) **(required)**: - `value` (number) **(required)**: Compatibility projection of valueExact for the lab currency. - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `completed` (object[]) **(required)**: - `date` (string) **(required)**: - `count` (number) **(required)**: - `value` (number) **(required)**: Compatibility projection of valueExact for the lab currency. - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `currencySeries` (object[]) **(required)**: - `currency` (string) **(required)**: Values: `GBP`, `EUR`, `USD`, `CAD`, `AUD`, `NZD`, `CHF`, `SEK`, `NOK`, `DKK`, `PLN`, `CZK`, `HUF`, `RON`, `INR`, `JPY`, `CNY`, `SGD`, `HKD`, `MXN`, `BRL`, `ZAR` - `series` (object) **(required)**: - `submitted` (object[]) **(required)**: - `date` (string) **(required)**: - `count` (number) **(required)**: - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `completed` (object[]) **(required)**: - `date` (string) **(required)**: - `count` (number) **(required)**: - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `totals` (object) **(required)**: - `submitted` (object) **(required)**: - `count` (number) **(required)**: - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `completed` (object) **(required)**: - `count` (number) **(required)**: - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `totals` (object) **(required)**: - `submitted` (object) **(required)**: - `count` (number) **(required)**: - `value` (number) **(required)**: - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `completed` (object) **(required)**: - `count` (number) **(required)**: - `value` (number) **(required)**: - `valueExact` (string) **(required)**: Exact decimal amount in major currency units. This string is authoritative; numeric money fields are compatibility projections. (example: `1234.56`) - `operations` (object): ### 401: Unauthorized — valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/dashboard/overview" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List time-off entries `GET https://api.guidelab.co/calendar/time-off` Returns paginated time-off and bank holiday entries for the authenticated lab. Optionally includes inactive entries. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/calendar/listCalendarTimeOff ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` () (in: query): Default: `false` - `page` (number) (in: query): Default: `1` - `limit` (number) (in: query): Default: `50` ## Responses ### 200: Paginated list of time-off entries - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `startDate` (string) **(required)**: - `endDate` (string) **(required)**: - `isRecurringAnnually` (boolean) **(required)**: - `isBankHoliday` (boolean) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 401: Unauthorized — valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/calendar/time-off" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a time-off entry `POST https://api.guidelab.co/calendar/time-off` Creates a new time-off or bank holiday entry for the authenticated lab. Validates that the start date is before or equal to the end date. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/calendar/createCalendarTimeOff ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `startDate` (string) **(required)**: - `endDate` (string) **(required)**: - `isRecurringAnnually` (boolean): (default: `false`) - `isBankHoliday` (boolean): (default: `false`) - `isActive` (boolean): (default: `true`) - `sortOrder` (integer): (default: `0`) ## Responses ### 201: Time-off entry created successfully - `entry` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `startDate` (string) **(required)**: - `endDate` (string) **(required)**: - `isRecurringAnnually` (boolean) **(required)**: - `isBankHoliday` (boolean) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/calendar/time-off" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "startDate": "string", "endDate": "string" }' ``` --- # Get a time-off entry by ID `GET https://api.guidelab.co/calendar/time-off/{id}` Returns a single time-off entry by ID, scoped to the authenticated lab. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/calendar/getCalendarTimeOff ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Time-off entry ID ## Responses ### 200: Time-off entry details - `entry` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `startDate` (string) **(required)**: - `endDate` (string) **(required)**: - `isRecurringAnnually` (boolean) **(required)**: - `isBankHoliday` (boolean) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — valid session required ### 404: Time-off entry not found ## Example ```bash curl -X GET "https://api.guidelab.co/calendar/time-off/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Deactivate a time-off entry `DELETE https://api.guidelab.co/calendar/time-off/{id}` Soft-deletes a time-off entry by setting it to inactive. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/calendar/deleteCalendarTimeOff ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Time-off entry ID ## Responses ### 200: Time-off entry deactivated successfully - `entry` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `isActive` (boolean) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `message` (string) **(required)**: ### 401: Unauthorized — valid session required ### 404: Time-off entry not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/calendar/time-off/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a time-off entry `PUT https://api.guidelab.co/calendar/time-off/{id}` Updates an existing time-off entry by ID. Validates date ordering. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/calendar/updateCalendarTimeOff ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Time-off entry ID ## Request Body Content-Type: `application/json` - `name` (string): - `startDate` (string): - `endDate` (string): - `isRecurringAnnually` (boolean): - `isBankHoliday` (boolean): - `isActive` (boolean): - `sortOrder` (integer): ## Responses ### 200: Time-off entry updated successfully - `entry` (object) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `startDate` (string) **(required)**: - `endDate` (string) **(required)**: - `isRecurringAnnually` (boolean) **(required)**: - `isBankHoliday` (boolean) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — valid session required ### 404: Time-off entry not found ## Example ```bash curl -X PUT "https://api.guidelab.co/calendar/time-off/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Seed UK bank holidays `POST https://api.guidelab.co/calendar/time-off/seed-holidays` Populates the lab's calendar with default UK bank holidays. Only seeds if the lab has no existing calendar entries. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/calendar/seedCalendarHolidays ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 201: Bank holidays seeded successfully - `message` (string) **(required)**: - `seeded` (boolean) **(required)**: - `count` (number) **(required)**: ### 401: Unauthorized — valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/calendar/time-off/seed-holidays" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get organization working days `GET https://api.guidelab.co/calendar/working-days` Returns the persisted working calendar for the authenticated organization or an explicitly selected active partner lab. Documentation: https://docs.guidelab.co/api-reference/calendar/getWorkingDays ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `labId` (string) (in: query): ## Responses ### 200: Array of working day numbers - `workingDays` (integer[]) **(required)**: - `timezone` (string) **(required)**: - `closures` (object[]) **(required)**: - `startDate` (string) **(required)**: - `endDate` (string) **(required)**: - `isRecurringAnnually` (boolean) **(required)**: ### 400: Requested organization is not a lab ### 401: Unauthorized — valid session required ### 403: The requested lab is not an active partner ### 404: Organization not found ## Example ```bash curl -X GET "https://api.guidelab.co/calendar/working-days" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update organization working days `PUT https://api.guidelab.co/calendar/working-days` Sets which days of the week (0=Sunday through 6=Saturday) the lab operates. At least one day must be selected. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/calendar/updateWorkingDays ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `workingDays` (integer[]) **(required)**: ## Responses ### 200: Working days updated successfully - `workingDays` (number[]) **(required)**: ### 401: Unauthorized — valid session required ## Example ```bash curl -X PUT "https://api.guidelab.co/calendar/working-days" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "workingDays": [ 0 ] }' ``` --- # List reports `GET https://api.guidelab.co/reports` Returns up to 500 accessible persisted built-in and custom report definitions for the authenticated lab; oversized directories fail explicitly. Documentation: https://docs.guidelab.co/api-reference/reports/listReports ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `type` (string) (in: query): Values: `built_in`, `custom` ## Responses ### 200: List of report definitions Array of: - `id` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `icon` (string) **(required)**: - `type` (string) **(required)**: Values: `built_in`, `custom` - `templateSlug` (string,null) **(required)**: - `isPinned` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: ### 401: Unauthorized — valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/reports" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a custom report `POST https://api.guidelab.co/reports` Creates a custom report after validating every versioned field and operator against its code-owned data-source adapter. Lab owner/admin only. Documentation: https://docs.guidelab.co/api-reference/reports/createReport ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `description` (string): - `icon` (string): - `config` (object) **(required)**: - `isPinned` (boolean): ## Responses ### 201: Custom report created successfully - `id` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `icon` (string) **(required)**: - `type` (string) **(required)**: Values: `built_in`, `custom` - `templateSlug` (string,null) **(required)**: - `isPinned` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: ### 400: Invalid report configuration ### 401: Unauthorized — valid session required ### 409: Report was modified concurrently ### 413: Report input or output limit exceeded ### 429: Report request budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/reports" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string", "icon": "string", "config": "string", "isPinned": true }' ``` --- # Report templates and saved reports `GET https://api.guidelab.co/reports/catalog` Documentation: https://docs.guidelab.co/api-reference/reports/getReportCatalog ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Accessible reports - `templates` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `icon` (string) **(required)**: - `type` (string) **(required)**: Values: `built_in`, `custom` - `templateSlug` (string,null) **(required)**: - `isPinned` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `config` (object) **(required)**: - `createdBy` (string,null) **(required)**: - `updatedAt` (string) **(required)**: - `category` (string): - `saved` (object[]) **(required)**: - `id` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `icon` (string) **(required)**: - `type` (string) **(required)**: Values: `built_in`, `custom` - `templateSlug` (string,null) **(required)**: - `isPinned` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `config` (object) **(required)**: - `createdBy` (string,null) **(required)**: - `updatedAt` (string) **(required)**: - `category` (string): - `canManage` (boolean) **(required)**: ## Example ```bash curl -X GET "https://api.guidelab.co/reports/catalog" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Preview an unsaved report `POST https://api.guidelab.co/reports/preview` Documentation: https://docs.guidelab.co/api-reference/reports/previewReport ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `config` (object) **(required)**: - `definitionVersion` (string) **(required)**: Values: `v2` - `dataset` (string) **(required)**: Values: `order_events`, `orders`, `production_tasks`, `technician_time`, `sales`, `sales_items`, `clients`, `receivables`, `cashflow`, `expenses`, `qc`, `remakes`, `shipments`, `stock`, `stock_movements` - `mode` (string) **(required)**: Values: `summary`, `detail` - `columns` (string[]) **(required)**: - `groupBy` (string[]): (default: ``) - `filters` (object[]): (default: ``) - `fieldKey` (string) **(required)**: - `operator` (string) **(required)**: Values: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `not_contains`, `in`, `not_in`, `between`, `is_null`, `is_not_null` - `value` (object): - `sortBy` (object[]): (default: ``) - `fieldKey` (string) **(required)**: - `direction` (string) **(required)**: Values: `asc`, `desc` - `dateField` (string): - `period` (object): (default: `[object Object]`) - `comparison` (string): (default: `none`) Values: `none`, `previous_period`, `previous_year` - `chart` (object): - `type` (string) **(required)**: Values: `bar`, `line`, `area`, `pie`, `donut` - `x` (string) **(required)**: - `y` (string) **(required)**: - `execution` (object) **(required)**: - `parameters` (object): - `period` (object): - `comparison` (string): Values: `none`, `previous_period`, `previous_year` - `filters` (object[]): - `fieldKey` (string) **(required)**: - `operator` (string) **(required)**: Values: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `not_contains`, `in`, `not_in`, `between`, `is_null`, `is_not_null` - `value` (object): - `drilldown` (boolean): - `drilldownFilters` (object[]): - `fieldKey` (string) **(required)**: - `operator` (string) **(required)**: Values: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `not_contains`, `in`, `not_in`, `between`, `is_null`, `is_not_null` - `value` (object): - `expectedUpdatedAt` (string): [date-time] - `page` (integer): (default: `1`) - `limit` (integer): (default: `50`) - `dateRange` (object): - `fieldKey` (string) **(required)**: - `preset` (string): Values: `today`, `yesterday`, `this_week`, `last_week`, `this_month`, `last_month`, `last_30_days`, `last_90_days`, `this_quarter`, `last_quarter`, `this_year`, `last_year`, `all_time` - `startDate` (string): - `endDate` (string): - `sortBy` (object[]): - `fieldKey` (string) **(required)**: - `direction` (string) **(required)**: Values: `asc`, `desc` - `additionalFilters` (object[]): - `fieldKey` (string) **(required)**: - `operator` (string) **(required)**: Values: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `not_contains`, `in`, `not_in`, `between`, `is_null`, `is_not_null` - `value` (object): ## Responses ### 200: Preview using the saved-report query contract - `definitionVersion` (string) **(required)**: Values: `v2` - `data` (object[]) **(required)**: - `columns` (object[]) **(required)**: - `key` (string) **(required)**: - `label` (string) **(required)**: - `type` (string) **(required)**: Values: `string`, `number`, `date`, `boolean`, `currency` - `format` (string): - `aggregation` (string): Values: `sum`, `count`, `avg`, `min`, `max` - `pagination` (object) **(required)**: - `page` (integer) **(required)**: - `limit` (integer) **(required)**: - `total` (integer) **(required)**: - `totalPages` (integer) **(required)**: - `summary` (object[]) **(required)**: - `comparison` (object[]) **(required)**: - `chart` (object[]) **(required)**: - `generatedAt` (string) **(required)**: [date-time] - `timeZone` (string) **(required)**: - `effective` (object) **(required)**: - `startDate` (string,null) **(required)**: - `endDate` (string,null) **(required)**: - `comparisonStart` (string,null) **(required)**: - `comparisonEnd` (string,null) **(required)**: - `filters` (object[]) **(required)**: - `fieldKey` (string) **(required)**: - `operator` (string) **(required)**: Values: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `not_contains`, `in`, `not_in`, `between`, `is_null`, `is_not_null` - `value` (object): - `coverage` (object) **(required)**: - `facts` (integer) **(required)**: - `missing` (integer) **(required)**: - `undated` (integer): (default: `0`) - `current` (boolean) **(required)**: - `partialPeriod` (boolean) **(required)**: ### 400: Invalid configuration ### 413: Input or output limit exceeded ### 429: Execution budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/reports/preview" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "config": { "definitionVersion": "v2", "dataset": "order_events", "mode": "summary", "columns": [ "string" ] }, "execution": {} }' ``` --- # List available report data sources `GET https://api.guidelab.co/reports/data-sources` Returns the serializable field, type, aggregation, sort, and filter allowlists for all four code-owned report adapters. Documentation: https://docs.guidelab.co/api-reference/reports/listReportDataSources ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `version` (string) (in: query): Values: `v1`, `v2` Default: `v1` ## Responses ### 200: Versioned data-source definitions ### 401: Unauthorized — valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/reports/data-sources" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get a report by ID `GET https://api.guidelab.co/reports/{id}` Returns one tenant-scoped report. Built-in slugs are expanded into their explicit adapter-backed configuration. Documentation: https://docs.guidelab.co/api-reference/reports/getReport ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Report details with executable configuration - `id` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `icon` (string) **(required)**: - `type` (string) **(required)**: Values: `built_in`, `custom` - `templateSlug` (string,null) **(required)**: - `isPinned` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `config` (object) **(required)**: - `createdBy` (string,null) **(required)**: - `updatedAt` (string) **(required)**: ### 401: Unauthorized — valid session required ### 404: Report not found ## Example ```bash curl -X GET "https://api.guidelab.co/reports/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a report `PATCH https://api.guidelab.co/reports/{id}` Updates a tenant-scoped report. Built-in query definitions cannot be replaced. Lab owner/admin only. Documentation: https://docs.guidelab.co/api-reference/reports/updateReport ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `name` (string): - `description` (string): - `icon` (string): - `config` (object): - `expectedUpdatedAt` (string): [date-time] - `isActive` (boolean): Values: `false` - `isPinned` (boolean): - `sortOrder` (integer): ## Responses ### 200: Report updated successfully - `success` (boolean) **(required)**: ### 400: Invalid report configuration ### 401: Unauthorized — valid session required ### 403: Built-in query definitions are immutable ### 404: Report not found ### 409: Report was modified concurrently ### 413: Report input or output limit exceeded ### 429: Report request budget exceeded ## Example ```bash curl -X PATCH "https://api.guidelab.co/reports/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Delete a custom report `DELETE https://api.guidelab.co/reports/{id}` Archives a legacy custom report. V2 reports must be archived through PATCH with expectedUpdatedAt. Built-in reports cannot be deleted. Lab owner/admin only. Documentation: https://docs.guidelab.co/api-reference/reports/deleteReport ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Report deleted successfully - `success` (boolean) **(required)**: ### 401: Unauthorized — valid session required ### 403: Cannot delete built-in reports ### 404: Report not found ### 409: V2 archival requires a versioned update ## Example ```bash curl -X DELETE "https://api.guidelab.co/reports/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Execute a report query `POST https://api.guidelab.co/reports/{id}/execute` Runs one adapter-backed, tenant-scoped report query with bounded fields, filters, sorts, pagination, and database time. Documentation: https://docs.guidelab.co/api-reference/reports/executeReport ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `parameters` (object): - `period` (object): - `comparison` (string): Values: `none`, `previous_period`, `previous_year` - `filters` (object[]): - `fieldKey` (string) **(required)**: - `operator` (string) **(required)**: Values: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `not_contains`, `in`, `not_in`, `between`, `is_null`, `is_not_null` - `value` (object): - `drilldown` (boolean): - `drilldownFilters` (object[]): - `fieldKey` (string) **(required)**: - `operator` (string) **(required)**: Values: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `not_contains`, `in`, `not_in`, `between`, `is_null`, `is_not_null` - `value` (object): - `expectedUpdatedAt` (string): [date-time] - `page` (integer): (default: `1`) - `limit` (integer): (default: `50`) - `dateRange` (object): - `fieldKey` (string) **(required)**: - `preset` (string): Values: `today`, `yesterday`, `this_week`, `last_week`, `this_month`, `last_month`, `last_30_days`, `last_90_days`, `this_quarter`, `last_quarter`, `this_year`, `last_year`, `all_time` - `startDate` (string): - `endDate` (string): - `sortBy` (object[]): - `fieldKey` (string) **(required)**: - `direction` (string) **(required)**: Values: `asc`, `desc` - `additionalFilters` (object[]): - `fieldKey` (string) **(required)**: - `operator` (string) **(required)**: Values: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `not_contains`, `in`, `not_in`, `between`, `is_null`, `is_not_null` - `value` (object): ## Responses ### 200: Paginated report execution results ### 400: Invalid report configuration ### 401: Unauthorized — valid session required ### 404: Report not found ### 408: Report query exceeded its time limit ### 409: Report was modified concurrently ### 413: Report input or output limit exceeded ### 429: Report request budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/reports/{id}/execute" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{}' ``` --- # Export a report as CSV `POST https://api.guidelab.co/reports/{id}/export` Executes one tenant-scoped report query and returns a synchronous CSV under fixed request, row, byte, time, and query-fan-out ceilings. Documentation: https://docs.guidelab.co/api-reference/reports/exportReport ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `parameters` (object): - `period` (object): - `comparison` (string): Values: `none`, `previous_period`, `previous_year` - `filters` (object[]): - `fieldKey` (string) **(required)**: - `operator` (string) **(required)**: Values: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `not_contains`, `in`, `not_in`, `between`, `is_null`, `is_not_null` - `value` (object): - `drilldown` (boolean): - `drilldownFilters` (object[]): - `fieldKey` (string) **(required)**: - `operator` (string) **(required)**: Values: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `not_contains`, `in`, `not_in`, `between`, `is_null`, `is_not_null` - `value` (object): - `expectedUpdatedAt` (string): [date-time] - `dateRange` (object): - `fieldKey` (string) **(required)**: - `preset` (string): Values: `today`, `yesterday`, `this_week`, `last_week`, `this_month`, `last_month`, `last_30_days`, `last_90_days`, `this_quarter`, `last_quarter`, `this_year`, `last_year`, `all_time` - `startDate` (string): - `endDate` (string): - `sortBy` (object[]): - `fieldKey` (string) **(required)**: - `direction` (string) **(required)**: Values: `asc`, `desc` - `additionalFilters` (object[]): - `fieldKey` (string) **(required)**: - `operator` (string) **(required)**: Values: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `not_contains`, `in`, `not_in`, `between`, `is_null`, `is_not_null` - `value` (object): - `format` (string): (default: `csv`) Values: `csv`, `print` ## Responses ### 200: Bounded CSV file download - `definitionVersion` (string) **(required)**: Values: `v2` - `data` (object[]) **(required)**: - `columns` (object[]) **(required)**: - `key` (string) **(required)**: - `label` (string) **(required)**: - `type` (string) **(required)**: Values: `string`, `number`, `date`, `boolean`, `currency` - `format` (string): - `aggregation` (string): Values: `sum`, `count`, `avg`, `min`, `max` - `pagination` (object) **(required)**: - `page` (integer) **(required)**: - `limit` (integer) **(required)**: - `total` (integer) **(required)**: - `totalPages` (integer) **(required)**: - `summary` (object[]) **(required)**: - `comparison` (object[]) **(required)**: - `chart` (object[]) **(required)**: - `generatedAt` (string) **(required)**: [date-time] - `timeZone` (string) **(required)**: - `effective` (object) **(required)**: - `startDate` (string,null) **(required)**: - `endDate` (string,null) **(required)**: - `comparisonStart` (string,null) **(required)**: - `comparisonEnd` (string,null) **(required)**: - `filters` (object[]) **(required)**: - `fieldKey` (string) **(required)**: - `operator` (string) **(required)**: Values: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `not_contains`, `in`, `not_in`, `between`, `is_null`, `is_not_null` - `value` (object): - `coverage` (object) **(required)**: - `facts` (integer) **(required)**: - `missing` (integer) **(required)**: - `undated` (integer): (default: `0`) - `current` (boolean) **(required)**: - `partialPeriod` (boolean) **(required)**: ### 400: Invalid report configuration ### 401: Unauthorized — valid session required ### 404: Report not found ### 408: Report export exceeded its time limit ### 409: Report was modified concurrently ### 413: Report export exceeded its row or byte limit ### 429: Report export request budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/reports/{id}/export" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "parameters": { "period": "string", "comparison": "none", "filters": [ { "fieldKey": "string", "operator": "eq", "value": "string" } ], "drilldown": true, "drilldownFilters": [ { "fieldKey": "string", "operator": "eq", "value": "string" } ] }, "expectedUpdatedAt": "string", "dateRange": { "fieldKey": "string", "preset": "today", "startDate": "string", "endDate": "string" }, "sortBy": [ { "fieldKey": "string", "direction": "asc" } ], "additionalFilters": [ { "fieldKey": "string", "operator": "eq", "value": "string" } ], "format": "csv" }' ``` --- # Export balance list as CSV `POST https://api.guidelab.co/export/balance-list` Exports the outstanding balance of each issued, unpaid invoice for the lab's clients as a CSV file. Caller specifies which fields to include. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/export/exportBalanceList ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `fields` (string[]) **(required)**: ## Responses ### 200: CSV file download with balance list data ### 401: Unauthorized — valid session required ### 429: CSV export budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/export/balance-list" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "fields": [ "string" ] }' ``` --- # Export clients as CSV `POST https://api.guidelab.co/export/clients` Exports the lab's active client relationships including contact info, price list, and practice group as a CSV file. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/export/exportClients ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `fields` (string[]) **(required)**: ## Responses ### 200: CSV file download with client data ### 401: Unauthorized — valid session required ### 429: CSV export budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/export/clients" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "fields": [ "string" ] }' ``` --- # Export price lists as CSV `POST https://api.guidelab.co/export/price-lists` Exports versioned product pricing rules with their stable book and publication metadata. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/export/exportPriceLists ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `fields` (string[]) **(required)**: ## Responses ### 200: CSV file download with price list data ### 401: Unauthorized — valid session required ### 413: CSV export lookup limit exceeded ### 429: CSV export budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/export/price-lists" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "fields": [ "string" ] }' ``` --- # Export products as CSV `POST https://api.guidelab.co/export/products` Exports the lab's active product catalog including categories, subcategories, standards, and pricing as a CSV file. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/export/exportProducts ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `fields` (string[]) **(required)**: ## Responses ### 200: CSV file download with product data ### 401: Unauthorized — valid session required ### 413: CSV export lookup limit exceeded ### 429: CSV export budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/export/products" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "fields": [ "string" ] }' ``` --- # Import balance list from CSV data `POST https://api.guidelab.co/import/balance-list` Imports non-negative opening balances as new invoices. Preserves a supplied invoice number when it is unused and rejects existing invoice numbers rather than mutating issued documents. Optionally saves the column mapping for reuse. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/import/importBalanceList ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `mappings` (object[]) **(required)**: - `sourceColumn` (string) **(required)**: - `targetField` (string) **(required)**: - `confidence` (number): - `rows` (object[]) **(required)**: - `skipErrors` (boolean): (default: `false`) - `saveMappingName` (string): ## Responses ### 200: Import results with success/error counts and created/updated IDs - `success` (boolean) **(required)**: - `totalRows` (number) **(required)**: - `successCount` (number) **(required)**: - `errorCount` (number) **(required)**: - `errors` (object[]) **(required)**: - `row` (integer) **(required)**: - `code` (string) **(required)**: Values: `required`, `invalid_value`, `not_found`, `product_identifier_required`, `price_or_discount_required`, `client_identifier_required`, `client_not_found`, `product_not_found`, `price_list_required`, `duplicate_row`, `client_not_importable`, `invoice_exists`, `currency_mismatch`, `product_has_bands`, `row_failed` - `message` (string) **(required)**: - `field` (string): - `value` (string): - `createdIds` (string[]) **(required)**: - `updatedIds` (string[]) **(required)**: ### 401: Unauthorized — valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/import/balance-list" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "mappings": [ { "sourceColumn": "string", "targetField": "string", "confidence": 0 } ], "rows": [ {} ], "skipErrors": true, "saveMappingName": "string" }' ``` --- # Import clients from CSV data `POST https://api.guidelab.co/import/clients` Imports clinic/client data from mapped CSV rows. Creates new clinic organizations and partnerships, or identifies existing ones. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/import/importClients ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `mappings` (object[]) **(required)**: - `sourceColumn` (string) **(required)**: - `targetField` (string) **(required)**: - `confidence` (number): - `rows` (object[]) **(required)**: - `skipErrors` (boolean): (default: `false`) - `saveMappingName` (string): ## Responses ### 200: Import results with success/error counts and created/updated IDs - `success` (boolean) **(required)**: - `totalRows` (number) **(required)**: - `successCount` (number) **(required)**: - `errorCount` (number) **(required)**: - `errors` (object[]) **(required)**: - `row` (integer) **(required)**: - `code` (string) **(required)**: Values: `required`, `invalid_value`, `not_found`, `product_identifier_required`, `price_or_discount_required`, `client_identifier_required`, `client_not_found`, `product_not_found`, `price_list_required`, `duplicate_row`, `client_not_importable`, `invoice_exists`, `currency_mismatch`, `product_has_bands`, `row_failed` - `message` (string) **(required)**: - `field` (string): - `value` (string): - `createdIds` (string[]) **(required)**: - `updatedIds` (string[]) **(required)**: ### 401: Unauthorized — valid session required ### 409: Client relationships changed during the import ## Example ```bash curl -X POST "https://api.guidelab.co/import/clients" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "mappings": [ { "sourceColumn": "string", "targetField": "string", "confidence": 0 } ], "rows": [ {} ], "skipErrors": true, "saveMappingName": "string" }' ``` --- # Import products from CSV data `POST https://api.guidelab.co/import/products` Imports product data from mapped CSV rows. Creates new products or updates existing ones matched by SKU. Auto-creates categories and subcategories as needed. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/import/importProducts ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `mappings` (object[]) **(required)**: - `sourceColumn` (string) **(required)**: - `targetField` (string) **(required)**: - `confidence` (number): - `rows` (object[]) **(required)**: - `skipErrors` (boolean): (default: `false`) - `saveMappingName` (string): ## Responses ### 200: Import results with success/error counts and created/updated IDs - `success` (boolean) **(required)**: - `totalRows` (number) **(required)**: - `successCount` (number) **(required)**: - `errorCount` (number) **(required)**: - `errors` (object[]) **(required)**: - `row` (integer) **(required)**: - `code` (string) **(required)**: Values: `required`, `invalid_value`, `not_found`, `product_identifier_required`, `price_or_discount_required`, `client_identifier_required`, `client_not_found`, `product_not_found`, `price_list_required`, `duplicate_row`, `client_not_importable`, `invoice_exists`, `currency_mismatch`, `product_has_bands`, `row_failed` - `message` (string) **(required)**: - `field` (string): - `value` (string): - `createdIds` (string[]) **(required)**: - `updatedIds` (string[]) **(required)**: ### 401: Unauthorized — valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/import/products" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "mappings": [ { "sourceColumn": "string", "targetField": "string", "confidence": 0 } ], "rows": [ {} ], "skipErrors": true, "saveMappingName": "string" }' ``` --- # Import price list items from CSV data `POST https://api.guidelab.co/import/price-lists` Imports price list items from mapped CSV rows. Supports single or multiple price list mode. Matches products by SKU or name. Auto-creates price lists in multiple mode. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/import/importPriceLists ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `mappings` (object[]) **(required)**: - `sourceColumn` (string) **(required)**: - `targetField` (string) **(required)**: - `confidence` (number): - `rows` (object[]) **(required)**: - `priceListId` (string): - `mode` (string): (default: `single`) Values: `single`, `multiple` - `skipErrors` (boolean): (default: `false`) - `saveMappingName` (string): ## Responses ### 200: Import results with success/error counts and created/updated IDs - `success` (boolean) **(required)**: - `totalRows` (number) **(required)**: - `successCount` (number) **(required)**: - `errorCount` (number) **(required)**: - `errors` (object[]) **(required)**: - `row` (integer) **(required)**: - `code` (string) **(required)**: Values: `required`, `invalid_value`, `not_found`, `product_identifier_required`, `price_or_discount_required`, `client_identifier_required`, `client_not_found`, `product_not_found`, `price_list_required`, `duplicate_row`, `client_not_importable`, `invoice_exists`, `currency_mismatch`, `product_has_bands`, `row_failed` - `message` (string) **(required)**: - `field` (string): - `value` (string): - `createdIds` (string[]) **(required)**: - `updatedIds` (string[]) **(required)**: ### 401: Unauthorized — valid session required ### 409: Price-list draft changed during import ## Example ```bash curl -X POST "https://api.guidelab.co/import/price-lists" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "mappings": [ { "sourceColumn": "string", "targetField": "string", "confidence": 0 } ], "rows": [ {} ], "priceListId": "string", "mode": "single", "skipErrors": true, "saveMappingName": "string" }' ``` --- # List saved import mappings `GET https://api.guidelab.co/import/mappings` Returns saved column mapping templates for the lab. Optionally filter by import type (products, clients, price_lists, balance_list). Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/import/listImportMappings ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of saved import mappings - `mappings` (array) **(required)**: ### 401: Unauthorized — valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/import/mappings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Save an import mapping template `POST https://api.guidelab.co/import/mappings` Saves a reusable column mapping template for future imports. Can be set as the default mapping for its import type. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/import/createImportMapping ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `importType` (string) **(required)**: Values: `products`, `clients`, `price_lists`, `balance_list` - `name` (string) **(required)**: - `mappings` (object[]) **(required)**: - `sourceColumn` (string) **(required)**: - `targetField` (string) **(required)**: - `confidence` (number): - `isDefault` (boolean): (default: `false`) ## Responses ### 201: Import mapping created successfully - `mapping` (object): ### 401: Unauthorized — valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/import/mappings" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "importType": "products", "name": "string", "mappings": [ { "sourceColumn": "string", "targetField": "string", "confidence": 0 } ], "isDefault": true }' ``` --- # Delete an import mapping template `DELETE https://api.guidelab.co/import/mappings` Permanently deletes a saved import mapping template by ID (passed as query parameter). Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/import/deleteImportMapping ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Import mapping deleted successfully - `success` (boolean) **(required)**: ### 401: Unauthorized — valid session required ### 404: Mapping not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/import/mappings" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Validate import data before importing `POST https://api.guidelab.co/import/validate` Dry-run validation of mapped CSV rows for a given import type. Returns per-row validation results and a summary of valid/invalid counts without persisting anything. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/import/validateImportData ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `importType` (string) **(required)**: Values: `products`, `clients`, `price_lists`, `balance_list` - `mappings` (object[]) **(required)**: - `sourceColumn` (string) **(required)**: - `targetField` (string) **(required)**: - `confidence` (number): - `rows` (object[]) **(required)**: - `mode` (string): Values: `single`, `multiple` - `priceListId` (string): ## Responses ### 200: Validation results with per-row errors and summary - `isValid` (boolean) **(required)**: - `errors` (object[]) **(required)**: - `row` (integer) **(required)**: - `field` (string) **(required)**: - `code` (string) **(required)**: Values: `required`, `invalid_value`, `not_found`, `product_identifier_required`, `price_or_discount_required`, `client_identifier_required`, `client_not_found`, `product_not_found`, `price_list_required`, `duplicate_row`, `client_not_importable`, `invoice_exists`, `currency_mismatch`, `product_has_bands`, `row_failed` - `message` (string) **(required)**: - `value` (string): - `severity` (string) **(required)**: Values: `error`, `warning`, `info` - `warnings` (object[]) **(required)**: - `row` (integer) **(required)**: - `field` (string) **(required)**: - `code` (string) **(required)**: Values: `required`, `invalid_value`, `not_found`, `product_identifier_required`, `price_or_discount_required`, `client_identifier_required`, `client_not_found`, `product_not_found`, `price_list_required`, `duplicate_row`, `client_not_importable`, `invoice_exists`, `currency_mismatch`, `product_has_bands`, `row_failed` - `message` (string) **(required)**: - `value` (string): - `severity` (string) **(required)**: Values: `error`, `warning`, `info` - `validRows` (integer) **(required)**: - `invalidRows` (integer) **(required)**: - `rowResults` (object[]) **(required)**: - `rowIndex` (integer) **(required)**: - `isValid` (boolean) **(required)**: - `data` (object) **(required)**: - `errors` (object[]) **(required)**: - `row` (integer) **(required)**: - `field` (string) **(required)**: - `code` (string) **(required)**: Values: `required`, `invalid_value`, `not_found`, `product_identifier_required`, `price_or_discount_required`, `client_identifier_required`, `client_not_found`, `product_not_found`, `price_list_required`, `duplicate_row`, `client_not_importable`, `invoice_exists`, `currency_mismatch`, `product_has_bands`, `row_failed` - `message` (string) **(required)**: - `value` (string): - `severity` (string) **(required)**: Values: `error`, `warning`, `info` - `warnings` (object[]) **(required)**: - `row` (integer) **(required)**: - `field` (string) **(required)**: - `code` (string) **(required)**: Values: `required`, `invalid_value`, `not_found`, `product_identifier_required`, `price_or_discount_required`, `client_identifier_required`, `client_not_found`, `product_not_found`, `price_list_required`, `duplicate_row`, `client_not_importable`, `invoice_exists`, `currency_mismatch`, `product_has_bands`, `row_failed` - `message` (string) **(required)**: - `value` (string): - `severity` (string) **(required)**: Values: `error`, `warning`, `info` - `summary` (object) **(required)**: - `total` (integer) **(required)**: - `valid` (integer) **(required)**: - `invalid` (integer) **(required)**: ### 401: Unauthorized — valid session required ## Example ```bash curl -X POST "https://api.guidelab.co/import/validate" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "importType": "products", "mappings": [ { "sourceColumn": "string", "targetField": "string", "confidence": 0 } ], "rows": [ {} ], "mode": "single", "priceListId": "string" }' ``` --- # Export selected domains as a re-importable zip bundle `POST https://api.guidelab.co/data-bundle/export` Streams a versioned zip containing the selected configuration domains (data files + binary assets + manifest). Lab owners only. Documentation: https://docs.guidelab.co/api-reference/data-bundle/exportDataBundle ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `domains` (string[]) **(required)**: - `includeFinanceTransactions` (boolean): (default: `false`) ## Responses ### 200: Zip bundle download ### 400: Invalid request ### 401: Unauthorized — valid session required ### 403: Lab owners only ### 429: Export budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/data-bundle/export" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "domains": [ "products" ], "includeFinanceTransactions": true }' ``` --- # Get a presigned PUT URL for uploading a bundle zip `POST https://api.guidelab.co/data-bundle/import/presign` Returns a presigned R2 upload URL for a bundle zip (max 250MB). The returned durable session ID is passed to analyze/execute; the storage key remains server-controlled. Lab owners only. Documentation: https://docs.guidelab.co/api-reference/data-bundle/presignDataBundleUpload ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `fileName` (string) **(required)**: - `size` (integer) **(required)**: ## Responses ### 200: Presigned upload URL - `uploadUrl` (string) **(required)**: - `sessionId` (string) **(required)**: - `uploadContentType` (string) **(required)**: ### 400: Invalid request ### 401: Unauthorized — valid session required ### 403: Lab owners only ### 429: Upload issuance budget exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/data-bundle/import/presign" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "fileName": "string", "size": 0 }' ``` --- # Dry-run an uploaded bundle against the current organization `POST https://api.guidelab.co/data-bundle/import/analyze` Parses the uploaded bundle and returns per-table created/updated/skipped counts plus warnings, without writing anything. Lab owners only. Documentation: https://docs.guidelab.co/api-reference/data-bundle/analyzeDataBundle ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `sessionId` (string) **(required)**: ## Responses ### 200: Dry-run result - `manifest` (object) **(required)**: - `formatVersion` (integer) **(required)**: - `bundleId` (string) **(required)**: - `exportedAt` (string) **(required)**: - `source` (object) **(required)**: - `orgId` (string) **(required)**: - `orgName` (string) **(required)**: - `orgType` (string) **(required)**: - `orgSlug` (string,null): - `host` (string): - `domains` (string[]) **(required)**: - `sameOrg` (boolean) **(required)**: - `crossEnv` (boolean) **(required)**: - `tables` (object[]) **(required)**: - `name` (string) **(required)**: - `domain` (string) **(required)**: Values: `products`, `production`, `templates`, `lab_settings`, `clients`, `finance`, `users` - `importable` (boolean) **(required)**: - `rowsInBundle` (integer) **(required)**: - `toCreate` (integer) **(required)**: - `toUpdate` (integer) **(required)**: - `toSkip` (integer) **(required)**: - `warnings` (object[]) **(required)**: - `code` (string) **(required)**: Values: `member_not_found`, `fk_missing`, `env_specific_stripped`, `columns_drift`, `export_only_table`, `json_id_dropped`, `ambiguous_match`, `tray_code_missing`, `row_invalid`, `asset_missing` - `message` (string) **(required)**: - `table` (string): - `count` (integer): - `sample` (string[]): - `assets` (object) **(required)**: - `count` (integer) **(required)**: - `totalBytes` (integer) **(required)**: - `blockers` (object[]) **(required)**: - `code` (string) **(required)**: Values: `format_version_unsupported`, `wrong_org_type`, `manifest_invalid`, `bundle_too_large`, `target_table_too_large`, `import_in_progress`, `category_cycle`, `target_organization_missing`, `catalog_money_invalid` - `message` (string) **(required)**: ### 400: Invalid request ### 401: Unauthorized — valid session required ### 403: Lab owners only ### 404: Uploaded bundle not found ### 409: Import session is terminal or already in use ## Example ```bash curl -X POST "https://api.guidelab.co/data-bundle/import/analyze" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "sessionId": "string" }' ``` --- # Import an uploaded bundle into the current organization `POST https://api.guidelab.co/data-bundle/import/execute` Re-plans the uploaded bundle and applies it: all ids are regenerated, references remapped, assets copied. One import at a time per organization. Lab owners only. Documentation: https://docs.guidelab.co/api-reference/data-bundle/executeDataBundleImport ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `sessionId` (string) **(required)**: - `domains` (string[]): - `conflictStrategy` (string): (default: `update`) Values: `update`, `skip` ## Responses ### 200: Import result - `success` (boolean) **(required)**: - `importLogId` (string): - `tables` (object[]) **(required)**: - `name` (string) **(required)**: - `domain` (string) **(required)**: Values: `products`, `production`, `templates`, `lab_settings`, `clients`, `finance`, `users` - `created` (integer) **(required)**: - `updated` (integer) **(required)**: - `skipped` (integer) **(required)**: - `warnings` (object[]) **(required)**: - `code` (string) **(required)**: Values: `member_not_found`, `fk_missing`, `env_specific_stripped`, `columns_drift`, `export_only_table`, `json_id_dropped`, `ambiguous_match`, `tray_code_missing`, `row_invalid`, `asset_missing` - `message` (string) **(required)**: - `table` (string): - `count` (integer): - `sample` (string[]): - `totals` (object) **(required)**: - `created` (integer) **(required)**: - `updated` (integer) **(required)**: - `skipped` (integer) **(required)**: - `warnings` (object[]) **(required)**: - `code` (string) **(required)**: Values: `member_not_found`, `fk_missing`, `env_specific_stripped`, `columns_drift`, `export_only_table`, `json_id_dropped`, `ambiguous_match`, `tray_code_missing`, `row_invalid`, `asset_missing` - `message` (string) **(required)**: - `table` (string): - `count` (integer): - `sample` (string[]): - `assetsCopied` (integer) **(required)**: ### 400: Invalid request or bundle has blockers ### 401: Unauthorized — valid session required ### 403: Lab owners only ### 404: Uploaded bundle not found ### 409: Another import is already running ## Example ```bash curl -X POST "https://api.guidelab.co/data-bundle/import/execute" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "sessionId": "string", "domains": [ "products" ], "conflictStrategy": "update" }' ``` --- # Generate an AI message for a conversation `POST https://api.guidelab.co/ai/generate` Uses gpt-5.6-luna to generate a contextually appropriate message for a conversation. Requires the organization to have AI assistance enabled, which is where the data-processing consent is recorded. Returns a Server-Sent Events stream. Rate limited to 10 requests per minute per user. Documentation: https://docs.guidelab.co/api-reference/ai/generateAiMessage ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `conversationId` (string) **(required)**: - `instruction` (string): ## Responses ### 200: SSE stream of generated message tokens ### 401: Unauthorized — valid session required ### 403: Not authorized for this conversation, or AI assistance is disabled for the organization ### 409: Conversation deletion has been authorized ### 413: AI prompt input limit exceeded ### 429: Global, organization, or user AI usage limit exceeded ## Example ```bash curl -X POST "https://api.guidelab.co/ai/generate" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "conversationId": "string", "instruction": "string" }' ``` --- # Global search across all entities `GET https://api.guidelab.co/search` Performs a fuzzy search across orders, patients, organizations, products (lab only), invoices, and team members within the authenticated organization's scope. Returns ranked results grouped by entity type. Documentation: https://docs.guidelab.co/api-reference/search/searchGlobal ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `q` (string) **(required)** (in: query): - `limit` (integer) (in: query): Default: `5` ## Responses ### 200: Search results grouped by entity type with relevance scores - `results` (object) **(required)**: - `orders` (object[]) **(required)**: - `id` (string) **(required)**: - `label` (string) **(required)**: - `subtitle` (string,null) **(required)**: - `code` (string,null) **(required)**: - `status` (string,null) **(required)**: - `dueDate` (string,null) **(required)**: - `amount` (string,null) **(required)**: - `currency` (string,null) **(required)**: - `url` (string) **(required)**: - `relevance` (number) **(required)**: - `patients` (object[]) **(required)**: - `id` (string) **(required)**: - `label` (string) **(required)**: - `subtitle` (string,null) **(required)**: - `code` (string,null) **(required)**: - `status` (string,null) **(required)**: - `dueDate` (string,null) **(required)**: - `amount` (string,null) **(required)**: - `currency` (string,null) **(required)**: - `url` (string) **(required)**: - `relevance` (number) **(required)**: - `organizations` (object[]) **(required)**: - `id` (string) **(required)**: - `label` (string) **(required)**: - `subtitle` (string,null) **(required)**: - `code` (string,null) **(required)**: - `status` (string,null) **(required)**: - `dueDate` (string,null) **(required)**: - `amount` (string,null) **(required)**: - `currency` (string,null) **(required)**: - `url` (string) **(required)**: - `relevance` (number) **(required)**: - `products` (object[]) **(required)**: - `id` (string) **(required)**: - `label` (string) **(required)**: - `subtitle` (string,null) **(required)**: - `code` (string,null) **(required)**: - `status` (string,null) **(required)**: - `dueDate` (string,null) **(required)**: - `amount` (string,null) **(required)**: - `currency` (string,null) **(required)**: - `url` (string) **(required)**: - `relevance` (number) **(required)**: - `invoices` (object[]) **(required)**: - `id` (string) **(required)**: - `label` (string) **(required)**: - `subtitle` (string,null) **(required)**: - `code` (string,null) **(required)**: - `status` (string,null) **(required)**: - `dueDate` (string,null) **(required)**: - `amount` (string,null) **(required)**: - `currency` (string,null) **(required)**: - `url` (string) **(required)**: - `relevance` (number) **(required)**: - `members` (object[]) **(required)**: - `id` (string) **(required)**: - `label` (string) **(required)**: - `subtitle` (string,null) **(required)**: - `code` (string,null) **(required)**: - `status` (string,null) **(required)**: - `dueDate` (string,null) **(required)**: - `amount` (string,null) **(required)**: - `currency` (string,null) **(required)**: - `url` (string) **(required)**: - `relevance` (number) **(required)**: - `query` (string) **(required)**: - `degraded` (string[]) **(required)**: Categories whose query failed and degraded to an empty list. Empty when every category ran successfully. (example: ``) ### 401: Unauthorized — valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/search" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Address suggestions for a partial address `GET https://api.guidelab.co/search/addresses` Proxies Google Places autocomplete, restricted to the platform's supported countries. `configured` is false when address lookup is not enabled for this deployment, in which case the list is always empty. Documentation: https://docs.guidelab.co/api-reference/search/searchAddresses ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `input` (string) **(required)** (in: query): - `sessionToken` (string) **(required)** (in: query): ## Responses ### 200: Up to five suggestions - `configured` (boolean) **(required)**: - `suggestions` (object[]) **(required)**: - `placeId` (string) **(required)**: - `text` (string) **(required)**: ### 401: Unauthorized — valid session required ### 429: Address lookup limit reached ## Example ```bash curl -X GET "https://api.guidelab.co/search/addresses" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Resolve one suggestion into a structured address `GET https://api.guidelab.co/search/addresses/{placeId}` Ends the autocomplete session and returns the address split into the fields the address forms store. Documentation: https://docs.guidelab.co/api-reference/search/resolveSearchAddress ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `placeId` (string) **(required)** (in: path): - `sessionToken` (string) **(required)** (in: query): ## Responses ### 200: Structured address - `address` (object) **(required)**: - `addressLine1` (string) **(required)**: - `addressLine2` (string) **(required)**: - `city` (string) **(required)**: - `state` (string) **(required)**: - `postcode` (string) **(required)**: - `country` (string) **(required)**: - `latitude` (number,null) **(required)**: - `longitude` (number,null) **(required)**: ### 401: Unauthorized — valid session required ### 404: Address not found ### 429: Address lookup limit reached ### 503: Address lookup is not configured ## Example ```bash curl -X GET "https://api.guidelab.co/search/addresses/{placeId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Download software installer for a platform `GET https://api.guidelab.co/download/{software}/{platform}` Fetches the newest matching software release asset from the private release repository and streams it to an authenticated user. Documentation: https://docs.guidelab.co/api-reference/download/downloadSoftwareInstaller ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `software` (string) **(required)** (in: path): Values: `uploader` - `platform` (string) **(required)** (in: path): Values: `mac-arm`, `mac-intel`, `windows` ## Responses ### 200: Binary file download stream ### 302: Redirect to a short-lived signed release asset URL ### 400: Unknown software or invalid platform ### 401: Unauthorized — valid session required ### 404: No matching release asset found ### 413: Release asset exceeds the download ceiling ### 429: Release lookup budget exhausted ### 502: Release service unavailable ## Example ```bash curl -X GET "https://api.guidelab.co/download/{software}/{platform}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Check for a signed uploader update `GET https://api.guidelab.co/download/uploader/update/{target}/{arch}/{currentVersion}` Returns signed Tauri updater metadata for the authenticated device, or no content when its installed version is current. Documentation: https://docs.guidelab.co/api-reference/download/checkUploaderUpdate ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `target` (string) **(required)** (in: path): Values: `darwin`, `windows` - `arch` (string) **(required)** (in: path): Values: `aarch64`, `x86_64` - `currentVersion` (string) **(required)** (in: path): ## Responses ### 200: Signed updater metadata - `version` (string) **(required)**: - `pub_date` (string): - `url` (string) **(required)**: [uri] - `signature` (string) **(required)**: - `notes` (string): ### 204: The installed version is current ### 400: Unsupported target or invalid version ### 401: Unauthorized — native device credential required ### 404: No signed update found ### 413: Release asset exceeds the download ceiling ### 429: Release lookup budget exhausted ### 502: Release service unavailable ## Example ```bash curl -X GET "https://api.guidelab.co/download/uploader/update/{target}/{arch}/{currentVersion}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Download a signed uploader update bundle `GET https://api.guidelab.co/download/uploader/update-asset/{version}/{assetName}` Streams an allowlisted updater bundle from an exact private release version to an authenticated device. Documentation: https://docs.guidelab.co/api-reference/download/downloadUploaderUpdateAsset ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `version` (string) **(required)** (in: path): - `assetName` (string) **(required)** (in: path): Values: `GuideLab-Uploader_aarch64.app.tar.gz`, `GuideLab-Uploader_x64.app.tar.gz`, `GuideLab-Uploader_x64.exe` ## Responses ### 200: Signed updater bundle ### 302: Redirect to a short-lived signed release asset URL ### 400: Unsupported updater asset ### 401: Unauthorized — native device credential required ### 404: Update asset not found ### 413: Release asset exceeds the download ceiling ### 429: Release lookup budget exhausted ### 502: Release service unavailable ## Example ```bash curl -X GET "https://api.guidelab.co/download/uploader/update-asset/{version}/{assetName}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List partner labs for the clinic `GET https://api.guidelab.co/clinic/labs` Returns all labs that have a partnership with the authenticated clinic, including lab contact details and partnership status. Clinic-only endpoint. Documentation: https://docs.guidelab.co/api-reference/clinic/getClinicPartnerLabs ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: List of partner labs with contact info and partnership status - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `labName` (string) **(required)**: - `labLogo` (string,null) **(required)**: - `labCity` (string,null) **(required)**: - `labPhone` (string,null) **(required)**: - `labEmail` (string,null) **(required)**: - `status` (string) **(required)**: - `createdAt` (string) **(required)**: ### 401: Unauthorized — valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/clinic/labs" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List clinic clients (doctors) for a lab `GET https://api.guidelab.co/clients` Returns paginated list of clinic owner members (doctors) from partner clinics. Supports search, filtering by clinic ID, and sorting by name, email, practice, or creation date. Includes per-doctor order counts. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/clients/listClients ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Paginated list of client members with order counts - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `userId` (string) **(required)**: - `userName` (string) **(required)**: - `userEmail` (string) **(required)**: - `userPhone` (string,null) **(required)**: - `role` (string) **(required)**: - `clinicId` (string) **(required)**: - `clinicName` (string) **(required)**: - `orderCount` (number) **(required)**: - `createdAt` (string) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 401: Unauthorized — valid session required ### 403: Only labs can access this endpoint ## Example ```bash curl -X GET "https://api.guidelab.co/clients" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Automations `GET https://api.guidelab.co/automations` Documentation: https://docs.guidelab.co/api-reference/automations/listAutomations ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `includeInactive` () (in: query): Default: `false` - `includeArchived` () (in: query): Default: `false` - `search` (string) (in: query): - `triggerType` (string) (in: query): Values: `order_created`, `order_status_changed`, `product_added_to_order`, `manual`, `qc_completed`, `scheduled_invoice_generation` - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `50` ## Responses ### 200: Paginated automations - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `triggerType` (string) **(required)**: - `triggerConfig` (object,null) **(required)**: - `flowDefinition` (object) **(required)**: - `activeRevisionId` (string,null) **(required)**: - `archivedAt` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query ### 403: Lab only ## Example ```bash curl -X GET "https://api.guidelab.co/automations" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Automation `POST https://api.guidelab.co/automations` Documentation: https://docs.guidelab.co/api-reference/automations/createAutomation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `name` (string) **(required)**: - `description` (string): - `triggerType` (string) **(required)**: Values: `order_created`, `order_status_changed`, `product_added_to_order`, `manual`, `qc_completed`, `scheduled_invoice_generation` - `triggerConfig` (object): - `flowDefinition` (object): - `nodes` (array) **(required)**: - `edges` (object[]) **(required)**: - `id` (string) **(required)**: - `source` (string) **(required)**: - `target` (string) **(required)**: - `sourceHandle` (string,null): - `targetHandle` (string,null): - `label` (string): - `sortOrder` (integer): (default: `0`) ## Responses ### 201: Created automation draft - `automation` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `triggerType` (string) **(required)**: - `triggerConfig` (object,null) **(required)**: - `flowDefinition` (object) **(required)**: - `activeRevisionId` (string,null) **(required)**: - `archivedAt` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid body ### 403: Lab only ## Example ```bash curl -X POST "https://api.guidelab.co/automations" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string", "triggerType": "order_created", "triggerConfig": {}, "flowDefinition": { "nodes": [ "string" ], "edges": [ { "id": "string", "source": "string", "target": "string", "sourceHandle": "string", "targetHandle": "string", "label": "string" } ] }, "sortOrder": 0 }' ``` --- # Get Automation `GET https://api.guidelab.co/automations/{id}` Documentation: https://docs.guidelab.co/api-reference/automations/getAutomation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Automation - `automation` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `triggerType` (string) **(required)**: - `triggerConfig` (object,null) **(required)**: - `flowDefinition` (object) **(required)**: - `activeRevisionId` (string,null) **(required)**: - `archivedAt` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 403: Lab only ### 404: Not found ## Example ```bash curl -X GET "https://api.guidelab.co/automations/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Toggle Automation `PATCH https://api.guidelab.co/automations/{id}` Documentation: https://docs.guidelab.co/api-reference/automations/toggleAutomation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `isActive` (boolean): ## Responses ### 200: Changed activation - `automation` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `triggerType` (string) **(required)**: - `triggerConfig` (object,null) **(required)**: - `flowDefinition` (object) **(required)**: - `activeRevisionId` (string,null) **(required)**: - `archivedAt` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Draft is not executable ### 403: Lab only ### 404: Not found ### 409: Archived ## Example ```bash curl -X PATCH "https://api.guidelab.co/automations/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "isActive": true }' ``` --- # Delete Automation `DELETE https://api.guidelab.co/automations/{id}` Documentation: https://docs.guidelab.co/api-reference/automations/deleteAutomation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Archived automation - `automation` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `triggerType` (string) **(required)**: - `triggerConfig` (object,null) **(required)**: - `flowDefinition` (object) **(required)**: - `activeRevisionId` (string,null) **(required)**: - `archivedAt` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `message` (string) **(required)**: ### 403: Lab only ### 404: Not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/automations/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Automation `PUT https://api.guidelab.co/automations/{id}` Documentation: https://docs.guidelab.co/api-reference/automations/updateAutomation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `name` (string): - `description` (string,null): - `triggerType` (string): Values: `order_created`, `order_status_changed`, `product_added_to_order`, `manual`, `qc_completed`, `scheduled_invoice_generation` - `triggerConfig` (object,null): - `flowDefinition` (object): - `nodes` (array) **(required)**: - `edges` (object[]) **(required)**: - `id` (string) **(required)**: - `source` (string) **(required)**: - `target` (string) **(required)**: - `sourceHandle` (string,null): - `targetHandle` (string,null): - `label` (string): - `sortOrder` (integer): ## Responses ### 200: Updated draft - `automation` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `triggerType` (string) **(required)**: - `triggerConfig` (object,null) **(required)**: - `flowDefinition` (object) **(required)**: - `activeRevisionId` (string,null) **(required)**: - `archivedAt` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid body ### 403: Lab only ### 404: Not found ### 409: Invalid or archived draft ## Example ```bash curl -X PUT "https://api.guidelab.co/automations/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "description": "string", "triggerType": "order_created", "triggerConfig": "string", "flowDefinition": { "nodes": [ "string" ], "edges": [ { "id": "string", "source": "string", "target": "string", "sourceHandle": "string", "targetHandle": "string", "label": "string" } ] }, "sortOrder": 0 }' ``` --- # Publish Automation `POST https://api.guidelab.co/automations/{id}/publish` Documentation: https://docs.guidelab.co/api-reference/automations/publishAutomation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `revisionKind` (string): (default: `published`) Values: `published`, `test` ## Responses ### 200: Published immutable revision - `automation` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `triggerType` (string) **(required)**: - `triggerConfig` (object,null) **(required)**: - `flowDefinition` (object) **(required)**: - `activeRevisionId` (string,null) **(required)**: - `archivedAt` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Draft is not executable ### 403: Lab only ### 404: Not found ### 409: Archived ## Example ```bash curl -X POST "https://api.guidelab.co/automations/{id}/publish" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "revisionKind": "published" }' ``` --- # Restore Automation `POST https://api.guidelab.co/automations/{id}/restore` Documentation: https://docs.guidelab.co/api-reference/automations/restoreAutomation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Restored automation (left inactive) - `automation` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `name` (string) **(required)**: - `description` (string,null) **(required)**: - `triggerType` (string) **(required)**: - `triggerConfig` (object,null) **(required)**: - `flowDefinition` (object) **(required)**: - `activeRevisionId` (string,null) **(required)**: - `archivedAt` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 403: Lab only ### 404: Not found ## Example ```bash curl -X POST "https://api.guidelab.co/automations/{id}/restore" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Automation Executions `GET https://api.guidelab.co/automations/{id}/executions` Documentation: https://docs.guidelab.co/api-reference/automations/listAutomationExecutions ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): - `status` (string) (in: query): Values: `queued`, `running`, `succeeded`, `failed`, `skipped`, `timed_out`, `cancelled` - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `50` ## Responses ### 200: Immutable execution history - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `automationId` (string) **(required)**: - `revisionId` (string) **(required)**: - `labId` (string) **(required)**: - `triggerKey` (string) **(required)**: - `triggerPayload` (object,null) **(required)**: - `acceptedByUserId` (string,null) **(required)**: - `status` (string) **(required)**: - `attemptCount` (number) **(required)**: - `queuedAt` (string) **(required)**: - `startedAt` (string,null) **(required)**: - `heartbeatAt` (string,null) **(required)**: - `completedAt` (string,null) **(required)**: - `error` (string,null) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 403: Lab only ## Example ```bash curl -X GET "https://api.guidelab.co/automations/{id}/executions" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Run Automation `POST https://api.guidelab.co/automations/{id}/run` Documentation: https://docs.guidelab.co/api-reference/automations/runAutomation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `triggerKey` (string) **(required)**: - `triggerPayload` (object): ## Responses ### 202: Execution durably accepted - `execution` (object) **(required)**: - `id` (string) **(required)**: - `automationId` (string) **(required)**: - `revisionId` (string) **(required)**: - `labId` (string) **(required)**: - `triggerKey` (string) **(required)**: - `triggerPayload` (object,null) **(required)**: - `acceptedByUserId` (string,null) **(required)**: - `status` (string) **(required)**: - `attemptCount` (number) **(required)**: - `queuedAt` (string) **(required)**: - `startedAt` (string,null) **(required)**: - `heartbeatAt` (string,null) **(required)**: - `completedAt` (string,null) **(required)**: - `error` (string,null) **(required)**: - `duplicate` (boolean) **(required)**: ### 400: Invalid body or trigger ### 403: Lab only ### 404: Not found ### 409: Inactive or conflicting trigger key ### 429: Manual automation acceptance budget exhausted ## Example ```bash curl -X POST "https://api.guidelab.co/automations/{id}/run" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "triggerKey": "string", "triggerPayload": {} }' ``` --- # List archived orders `GET https://api.guidelab.co/archive/orders` Returns paginated archived orders for active clinic partnerships. Hidden patient names are masked and excluded from search. Supports filtering by clinic ID. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/archive/listArchivedOrders ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Paginated list of archived orders with patient and clinic info - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `status` (string) **(required)**: - `createdAt` (string) **(required)**: - `archivedAt` (string) **(required)**: - `archivedByUser` (object): - `archivedByUserNameMissing` (boolean) **(required)**: - `patient` (object): - `patientFirstNameMissing` (boolean) **(required)**: - `clinic` (object): - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 401: Unauthorized — valid session required ### 403: Only labs can access the archive ## Example ```bash curl -X GET "https://api.guidelab.co/archive/orders" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Archive an order `POST https://api.guidelab.co/archive/orders` Archives a completed or cancelled order by setting its archivedAt timestamp. Shipment status is independent. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/archive/archiveOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Order archived successfully - `success` (boolean) **(required)**: - `order` (object) **(required)**: - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `archivedAt` (string): ### 400: Order is already archived or has invalid status ### 401: Unauthorized — valid session required ### 404: Order not found ### 409: Order changed before it could be archived ## Example ```bash curl -X POST "https://api.guidelab.co/archive/orders" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Restore an archived order `POST https://api.guidelab.co/archive/orders/restore` Removes the archived status from an order, making it active again. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/archive/restoreArchivedOrder ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Order restored successfully - `success` (boolean) **(required)**: - `order` (object) **(required)**: - `id` (string) **(required)**: - `orderNumber` (string) **(required)**: - `status` (string) **(required)**: ### 401: Unauthorized — valid session required ### 404: Archived order not found ### 409: Order changed before it could be restored ## Example ```bash curl -X POST "https://api.guidelab.co/archive/orders/restore" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List archived patients `GET https://api.guidelab.co/archive/patients` Returns paginated archived patients whose PII is shared through an active partnership or an explicit patient grant. Inaccessible patients are omitted. Supports search and clinic filtering. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/archive/listArchivedPatients ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Paginated list of archived patients with clinic and order info - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `clinicId` (string,null) **(required)**: - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: - `fullName` (string) **(required)**: - `externalId` (string,null) **(required)**: - `clinic` (object): - `orderCount` (number) **(required)**: - `createdAt` (string) **(required)**: - `archivedAt` (string) **(required)**: - `archivedByUser` (object): - `archivedByUserNameMissing` (boolean) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 401: Unauthorized — valid session required ### 403: Only labs can access the archive ## Example ```bash curl -X GET "https://api.guidelab.co/archive/patients" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Archive a patient `POST https://api.guidelab.co/archive/patients` Archives a patient by setting its archivedAt timestamp. Fails if the patient has active (non-archived) orders. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/archive/archivePatient ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Patient archived successfully - `success` (boolean) **(required)**: - `patient` (object) **(required)**: - `id` (string) **(required)**: - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: - `archivedAt` (string): - `warning` (string,null) **(required)**: ### 400: Patient already archived or has active orders ### 401: Unauthorized — valid session required ### 404: Patient not found ### 409: Patient changed before it could be archived ## Example ```bash curl -X POST "https://api.guidelab.co/archive/patients" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Restore an archived patient `POST https://api.guidelab.co/archive/patients/restore` Removes the archived status from a patient, making them active again. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/archive/restoreArchivedPatient ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Patient restored successfully - `success` (boolean) **(required)**: - `patient` (object) **(required)**: - `id` (string) **(required)**: - `firstName` (string) **(required)**: - `lastName` (string) **(required)**: ### 401: Unauthorized — valid session required ### 404: Archived patient not found ### 409: Patient changed before it could be restored ## Example ```bash curl -X POST "https://api.guidelab.co/archive/patients/restore" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List location routes `GET https://api.guidelab.co/location-routes` Returns paginated delivery location routes for a lab. Labs see their own routes; clinics must specify a labId query parameter and must be active partners of that lab. Documentation: https://docs.guidelab.co/api-reference/location-routes/listLocationRoutes ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Paginated list of location routes - `data` (array) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 401: Unauthorized — valid session required ## Example ```bash curl -X GET "https://api.guidelab.co/location-routes" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a location route `POST https://api.guidelab.co/location-routes` Creates a new delivery location route. If set as default, the previous default is unset. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/location-routes/createLocationRoute ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 201: Location route created successfully - `route` (object): ### 401: Unauthorized — valid session required ### 403: Only labs can create location routes ## Example ```bash curl -X POST "https://api.guidelab.co/location-routes" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get a location route by ID `GET https://api.guidelab.co/location-routes/{id}` Returns a single location route by ID. Labs see their own routes; clinics can only access routes from partner labs. Documentation: https://docs.guidelab.co/api-reference/location-routes/getLocationRoute ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Location route ID ## Responses ### 200: Location route details - `route` (object): ### 401: Unauthorized — valid session required ### 404: Location route not found ## Example ```bash curl -X GET "https://api.guidelab.co/location-routes/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Deactivate a location route `DELETE https://api.guidelab.co/location-routes/{id}` Soft-deletes a location route by setting it to inactive. Cannot delete the default route. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/location-routes/deleteLocationRoute ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Location route ID ## Responses ### 200: Location route deactivated successfully - `route` (object): - `message` (string) **(required)**: ### 400: Cannot delete the default route ### 401: Unauthorized — valid session required ### 403: Only labs can delete location routes ### 404: Location route not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/location-routes/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a location route `PUT https://api.guidelab.co/location-routes/{id}` Updates a location route's properties. If set as default, the previous default is unset. Lab-only endpoint. Documentation: https://docs.guidelab.co/api-reference/location-routes/updateLocationRoute ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Location route ID ## Responses ### 200: Location route updated successfully - `route` (object): ### 401: Unauthorized — valid session required ### 403: Only labs can update location routes ### 404: Location route not found ## Example ```bash curl -X PUT "https://api.guidelab.co/location-routes/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List clinic locations `GET https://api.guidelab.co/clinic-locations` Returns paginated clinic locations. Clinics see their own locations; labs must specify a clinicId query parameter and must have an active partnership with that clinic. Documentation: https://docs.guidelab.co/api-reference/clinic-locations/listClinicLocations ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Paginated list of clinic locations - `data` (array) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 401: Unauthorized — valid session required ### 403: Access denied to this clinic's locations ## Example ```bash curl -X GET "https://api.guidelab.co/clinic-locations" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create a clinic location `POST https://api.guidelab.co/clinic-locations` Creates a new physical location for the authenticated clinic. If set as default, the previous default is unset. Clinic-only endpoint. Documentation: https://docs.guidelab.co/api-reference/clinic-locations/createClinicLocation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 201: Clinic location created successfully - `location` (object): ### 401: Unauthorized — valid session required ### 403: Only clinics can create locations ## Example ```bash curl -X POST "https://api.guidelab.co/clinic-locations" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Get a clinic location by ID `GET https://api.guidelab.co/clinic-locations/{id}` Returns a single clinic location by ID. Documentation: https://docs.guidelab.co/api-reference/clinic-locations/getClinicLocation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Clinic location ID ## Responses ### 200: Clinic location details - `location` (object): ### 401: Unauthorized — valid session required ### 404: Location not found ## Example ```bash curl -X GET "https://api.guidelab.co/clinic-locations/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Deactivate a clinic location `DELETE https://api.guidelab.co/clinic-locations/{id}` Soft-deletes a clinic location by setting it to inactive. Cannot delete the default location. Clinic-only endpoint. Documentation: https://docs.guidelab.co/api-reference/clinic-locations/deleteClinicLocation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Clinic location ID ## Responses ### 200: Location deactivated successfully - `location` (object): - `message` (string) **(required)**: ### 400: Cannot delete the default location ### 401: Unauthorized — valid session required ### 403: Only clinics can delete locations ### 404: Location not found ## Example ```bash curl -X DELETE "https://api.guidelab.co/clinic-locations/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update a clinic location `PUT https://api.guidelab.co/clinic-locations/{id}` Updates a clinic location's properties. If set as default, the previous default is unset. Clinic-only endpoint. Documentation: https://docs.guidelab.co/api-reference/clinic-locations/updateClinicLocation ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): Clinic location ID ## Responses ### 200: Clinic location updated successfully - `location` (object): ### 401: Unauthorized — valid session required ### 403: Only clinics can update locations ### 404: Location not found ## Example ```bash curl -X PUT "https://api.guidelab.co/clinic-locations/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Handle Stripe Connect webhook events `POST https://api.guidelab.co/webhooks/stripe-connect` Receives verified Stripe Connect account, PaymentIntent, refund, and dispute events. Public endpoint; provider signature authentication is required outside explicit local test mode. Documentation: https://docs.guidelab.co/api-reference/webhooks/handleStripeConnectWebhook ## Responses ### 200: Webhook event processed successfully - `received` (boolean) **(required)**: ### 400: Invalid signature, payload, mode, or provenance ### 413: Webhook body exceeds the allowed size ### 500: Webhook processing failed ### 503: Webhook authentication is not configured safely ## Example ```bash curl -X POST "https://api.guidelab.co/webhooks/stripe-connect" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Handle Medit scanner webhook events `POST https://api.guidelab.co/webhooks/medit` Legacy Medit webhook URL for deliveries containing endpointUuid. Requires the endpoint-specific HMAC; new registrations use the connection-specific URL. No session authentication. Documentation: https://docs.guidelab.co/api-reference/webhooks/handleMeditWebhook ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Responses ### 200: Webhook event acknowledged - `ok` (boolean) **(required)**: ### 400: Invalid JSON payload ### 401: Missing or invalid webhook signature ### 413: Webhook body exceeds the allowed size ### 500: Webhook evidence could not be stored ### 503: Webhook signature is not configured ## Example ```bash curl -X POST "https://api.guidelab.co/webhooks/medit" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Handle Medit events for one scanner connection `POST https://api.guidelab.co/webhooks/medit/{connectionId}` Verifies the raw-body HMAC for the connected account identified by the URL. Medit resource events need no endpointUuid or event field; verified deliveries trigger a bounded account sync. Documentation: https://docs.guidelab.co/api-reference/webhooks/handleMeditConnectionWebhook ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `connectionId` (string) **(required)** (in: path): ## Responses ### 200: Webhook event acknowledged - `ok` (boolean) **(required)**: ### 400: Invalid JSON payload ### 401: Missing or invalid webhook signature ### 413: Webhook body exceeds the allowed size ### 500: Webhook evidence could not be stored ### 503: Webhook signature is not configured ## Example ```bash curl -X POST "https://api.guidelab.co/webhooks/medit/{connectionId}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Handle Alliedstar scan-result and order notifications `POST https://api.guidelab.co/webhooks/alliedstar` Receives Alliedstar asynchronous notifications. The signature travels in the body as `sign` and is verified against the open platform public key. Public endpoint; no session authentication. Documentation: https://docs.guidelab.co/api-reference/webhooks/handleAlliedStarWebhook ## Responses ### 200: Notification acknowledged with the vendor's success envelope - `code` (string) **(required)**: - `msg` (string) **(required)**: ### 400: Invalid JSON payload ### 401: Missing or invalid payload signature ### 413: Notification body exceeds the allowed size ### 500: Notification evidence could not be stored ### 503: Alliedstar signature verification is not configured ## Example ```bash curl -X POST "https://api.guidelab.co/webhooks/alliedstar" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Handle iTero scan notifications `POST https://api.guidelab.co/webhooks/itero/{connectionId}/{token}` Accepts bounded notification hints for the paired company, authenticated by an owner-bound URL token. Clinical data is retrieved separately using the connection's provider credentials. Documentation: https://docs.guidelab.co/api-reference/webhooks/handleIteroWebhook ## Parameters - `connectionId` (string) **(required)** (in: path): - `token` (string) **(required)** (in: path): ## Responses ### 200: Notification acknowledged - `ok` (boolean) **(required)**: ### 400: Invalid notification payload ### 401: Invalid notification credential or account ### 413: Notification exceeds the body limit ### 500: Notification could not be persisted ### 503: Notification authentication is unavailable ## Example ```bash curl -X POST "https://api.guidelab.co/webhooks/itero/{connectionId}/{token}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Handle ShipEngine tracking webhook events `POST https://api.guidelab.co/webhooks/ship-engine/{integrationId}/{token}` Receives exact ShipEngine API_TRACK payloads authenticated by a per-integration URL token and ShipEngine RSA signature. Documentation: https://docs.guidelab.co/api-reference/webhooks/handleShipEngineTrackingWebhook ## Parameters - `integrationId` (string) **(required)** (in: path): - `token` (string) **(required)** (in: path): ## Responses ### 200: Webhook evidence accepted - `ok` (boolean) **(required)**: - `duplicate` (boolean) **(required)**: ### 400: Invalid webhook payload ### 401: Missing, invalid, or expired provider signature ### 404: Webhook endpoint not found ### 413: Webhook body exceeds the allowed size ### 429: Webhook verification budget exhausted ### 500: Webhook evidence could not be stored ## Example ```bash curl -X POST "https://api.guidelab.co/webhooks/ship-engine/{integrationId}/{token}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Answer the Meta webhook verification handshake `GET https://api.guidelab.co/webhooks/whatsapp` Echoes hub.challenge when hub.verify_token matches the configured Meta verify token. Public endpoint. Documentation: https://docs.guidelab.co/api-reference/webhooks/verifyWhatsAppWebhook ## Parameters - `hub.mode` (string) (in: query): - `hub.verify_token` (string) (in: query): - `hub.challenge` (string) (in: query): ## Responses ### 200: The challenge ### 403: Verify token mismatch ### 404: Meta channels are not configured ## Example ```bash curl -X GET "https://api.guidelab.co/webhooks/whatsapp" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Receive WhatsApp Cloud API events `POST https://api.guidelab.co/webhooks/whatsapp` Signed (X-Hub-Signature-256) Meta deliveries for WhatsApp, Messenger and Instagram. Messages and statuses are queued for ingestion; template and account updates are applied. Public endpoint. Documentation: https://docs.guidelab.co/api-reference/webhooks/handleWhatsAppWebhook ## Responses ### 200: Delivery acknowledged - `ok` (boolean) **(required)**: ### 400: Invalid payload ### 401: Missing or invalid signature ### 404: Meta channels are not configured ### 413: Webhook body too large ### 500: Events could not be queued; Meta redelivers ## Example ```bash curl -X POST "https://api.guidelab.co/webhooks/whatsapp" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Answer the Meta webhook verification handshake `GET https://api.guidelab.co/webhooks/meta` Echoes hub.challenge when hub.verify_token matches the configured Meta verify token. Public endpoint. Documentation: https://docs.guidelab.co/api-reference/webhooks/verifyMetaMessagingWebhook ## Parameters - `hub.mode` (string) (in: query): - `hub.verify_token` (string) (in: query): - `hub.challenge` (string) (in: query): ## Responses ### 200: The challenge ### 403: Verify token mismatch ### 404: Meta channels are not configured ## Example ```bash curl -X GET "https://api.guidelab.co/webhooks/meta" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Receive Messenger and Instagram events `POST https://api.guidelab.co/webhooks/meta` Signed (X-Hub-Signature-256) Meta deliveries for WhatsApp, Messenger and Instagram. Messages and statuses are queued for ingestion; template and account updates are applied. Public endpoint. Documentation: https://docs.guidelab.co/api-reference/webhooks/handleMetaMessagingWebhook ## Responses ### 200: Delivery acknowledged - `ok` (boolean) **(required)**: ### 400: Invalid payload ### 401: Missing or invalid signature ### 404: Meta channels are not configured ### 413: Webhook body too large ### 500: Events could not be queued; Meta redelivers ## Example ```bash curl -X POST "https://api.guidelab.co/webhooks/meta" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Receive inbound Twilio SMS and WhatsApp messages `POST https://api.guidelab.co/webhooks/twilio/{token}` Routed by a self-authenticating connection token, then verified with the lab's own Twilio auth token (X-Twilio-Signature over the canonical URL). Public endpoint. Documentation: https://docs.guidelab.co/api-reference/webhooks/handleTwilioChannelWebhook ## Parameters - `token` (string) **(required)** (in: path): ## Responses ### 200: Empty TwiML ### 401: Missing or invalid signature ### 404: Unknown routing token ### 413: Webhook body too large ### 500: Events could not be queued; Twilio redelivers ## Example ```bash curl -X POST "https://api.guidelab.co/webhooks/twilio/{token}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Receive Twilio delivery status callbacks `POST https://api.guidelab.co/webhooks/twilio/{token}/status` Routed by a self-authenticating connection token, then verified with the lab's own Twilio auth token (X-Twilio-Signature over the canonical URL). Public endpoint. Documentation: https://docs.guidelab.co/api-reference/webhooks/handleTwilioChannelStatusWebhook ## Parameters - `token` (string) **(required)** (in: path): ## Responses ### 200: Empty TwiML ### 401: Missing or invalid signature ### 404: Unknown routing token ### 413: Webhook body too large ### 500: Events could not be queued; Twilio redelivers ## Example ```bash curl -X POST "https://api.guidelab.co/webhooks/twilio/{token}/status" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Receive Telegram bot updates `POST https://api.guidelab.co/webhooks/telegram/{token}` Routed by a self-authenticating connection token and verified with the derived X-Telegram-Bot-Api-Secret-Token header without a database read. Public endpoint. Documentation: https://docs.guidelab.co/api-reference/webhooks/handleTelegramChannelWebhook ## Parameters - `token` (string) **(required)** (in: path): ## Responses ### 200: Delivery acknowledged - `ok` (boolean) **(required)**: ### 400: Invalid payload ### 401: Missing or invalid secret token ### 404: Unknown routing token ### 413: Webhook body too large ### 500: Update could not be queued; Telegram redelivers ## Example ```bash curl -X POST "https://api.guidelab.co/webhooks/telegram/{token}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Receive Gmail mailbox change pushes `POST https://api.guidelab.co/webhooks/mailbox/google/pubsub` Google Cloud Pub/Sub push authenticated by an OIDC token for GuideLab's push service account. Requests one coalesced mailbox sync. Public endpoint. Documentation: https://docs.guidelab.co/api-reference/webhooks/handleGmailPubSubPush ## Responses ### 204: Push acknowledged ### 401: Missing or invalid OIDC token ### 404: Gmail is not configured ### 413: Push body too large ### 500: Sync could not be queued; Pub/Sub redelivers ## Example ```bash curl -X POST "https://api.guidelab.co/webhooks/mailbox/google/pubsub" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Receive Outlook inbox change notifications `POST https://api.guidelab.co/webhooks/mailbox/microsoft/{token}` Microsoft Graph change notifications for one routed mailbox. Answers the validationToken handshake without a database read; each notification's clientState is verified before one coalesced mailbox sync is requested. Public endpoint. Documentation: https://docs.guidelab.co/api-reference/webhooks/handleOutlookMailboxNotification ## Parameters - `token` (string) **(required)** (in: path): - `validationToken` (string) (in: query): ## Responses ### 200: Validation token echo ### 202: Notifications accepted ### 400: Invalid payload ### 404: Unknown routing token ### 413: Notification body too large ### 500: Sync could not be queued; Graph redelivers ## Example ```bash curl -X POST "https://api.guidelab.co/webhooks/mailbox/microsoft/{token}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Receive Outlook subscription lifecycle notifications `POST https://api.guidelab.co/webhooks/mailbox/microsoft/{token}/lifecycle` Microsoft Graph change notifications for one routed mailbox. Answers the validationToken handshake without a database read; each notification's clientState is verified before one coalesced mailbox sync is requested. Public endpoint. Documentation: https://docs.guidelab.co/api-reference/webhooks/handleOutlookMailboxLifecycle ## Parameters - `token` (string) **(required)** (in: path): - `validationToken` (string) (in: query): ## Responses ### 200: Validation token echo ### 202: Notifications accepted ### 400: Invalid payload ### 404: Unknown routing token ### 413: Notification body too large ### 500: Sync could not be queued; Graph redelivers ## Example ```bash curl -X POST "https://api.guidelab.co/webhooks/mailbox/microsoft/{token}/lifecycle" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Serve one outbound attachment to a messaging provider `GET https://api.guidelab.co/webhooks/channel-media/{token}` Short-lived (15 minute) HMAC URL for providers that fetch media by URL (Messenger, Instagram, Twilio). The token is verified before any storage read. Public endpoint. Documentation: https://docs.guidelab.co/api-reference/webhooks/getSignedChannelMediaForProvider ## Parameters - `token` (string) **(required)** (in: path): ## Responses ### 200: Attachment bytes ### 404: Unknown, expired or retired media ### 429: Media read budget exhausted ## Example ```bash curl -X GET "https://api.guidelab.co/webhooks/channel-media/{token}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # List Work Trays `GET https://api.guidelab.co/work-trays` List work trays for the current lab with pagination, search, and optional order filtering. Includes the currently assigned order for each tray. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/work-trays/listWorkTrays ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `page` (integer) (in: query): Default: `1` - `limit` (integer) (in: query): Default: `50` - `search` (string) (in: query): - `orderId` (string) (in: query): - `includeInactive` () (in: query): Default: `false` ## Responses ### 200: Paginated list of work trays with current order assignments - `data` (object[]) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `code` (string) **(required)**: - `color` (string,null): - `description` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `currentOrderId` (string,null) **(required)**: - `currentOrderNumber` (string,null) **(required)**: - `currentOrderPhaseId` (string,null) **(required)**: - `currentPhaseName` (string,null) **(required)**: - `pagination` (object) **(required)**: - `page` (number) **(required)**: - `limit` (number) **(required)**: - `total` (number) **(required)**: - `totalPages` (number) **(required)**: ### 400: Invalid query parameters ### 403: Only labs can access work trays ### 500: Internal server error ## Example ```bash curl -X GET "https://api.guidelab.co/work-trays" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Create Work Tray `POST https://api.guidelab.co/work-trays` Create a new work tray with a unique code. Lab-only operation. Returns 409 if a tray with the same code already exists. Documentation: https://docs.guidelab.co/api-reference/work-trays/createWorkTray ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `code` (string) **(required)**: - `color` (string): - `description` (string): - `isActive` (boolean): (default: `true`) - `sortOrder` (integer): (default: `0`) ## Responses ### 201: Newly created work tray - `tray` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `code` (string) **(required)**: - `color` (string,null): - `description` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 403: Only labs can create work trays ### 409: A tray with this code already exists ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/work-trays" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "code": "string", "color": "string", "description": "string", "isActive": true, "sortOrder": 0 }' ``` --- # Batch Create Work Trays `POST https://api.guidelab.co/work-trays/batch` Bulk-create work trays from a pattern and quantity. Generates sequentially numbered codes (e.g. TRAY001, TRAY002). Skips duplicates. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/work-trays/batchCreateWorkTrays ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Request Body Content-Type: `application/json` - `pattern` (string) **(required)**: - `quantity` (integer) **(required)**: - `color` (string): - `description` (string): ## Responses ### 201: Batch creation result with created count and duplicate errors - `created` (number) **(required)**: - `total` (number) **(required)**: - `errors` (object[]) **(required)**: - `code` (string) **(required)**: - `error` (string) **(required)**: ### 400: Invalid request body ### 500: Internal server error ## Example ```bash curl -X POST "https://api.guidelab.co/work-trays/batch" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "pattern": "string", "quantity": 0, "color": "string", "description": "string" }' ``` --- # Delete Work Tray `DELETE https://api.guidelab.co/work-trays/{id}` Soft-delete a work tray by marking it as inactive. Unassigns the tray from any active orders before deactivating. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/work-trays/deleteWorkTray ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Responses ### 200: Tray deactivated and unassigned from active orders - `tray` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `code` (string) **(required)**: - `color` (string,null): - `description` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: - `message` (string) **(required)**: ### 403: Only labs can delete work trays ### 404: Tray not found ### 500: Internal server error ## Example ```bash curl -X DELETE "https://api.guidelab.co/work-trays/{id}" \ -H "Authorization: Bearer gl_device_v1_" ``` --- # Update Work Tray `PUT https://api.guidelab.co/work-trays/{id}` Update an existing work tray's code, color, description, active status, or sort order. Returns 409 if the new code conflicts with an existing tray. Lab-only operation. Documentation: https://docs.guidelab.co/api-reference/work-trays/updateWorkTray ## Authentication Requires an authenticated browser session (`__Secure-guidelab-prod.session_token` cookie) or a versioned GuideLab device credential in the `Authorization` header. Better Auth session tokens are cookie-only and are not valid bearer credentials. ``` Authorization: Bearer gl_device_v1_ ``` ## Parameters - `id` (string) **(required)** (in: path): ## Request Body Content-Type: `application/json` - `code` (string): - `color` (string): - `description` (string): - `isActive` (boolean): - `sortOrder` (integer): ## Responses ### 200: Successfully updated work tray - `tray` (object) **(required)**: - `id` (string) **(required)**: - `labId` (string) **(required)**: - `code` (string) **(required)**: - `color` (string,null): - `description` (string,null) **(required)**: - `isActive` (boolean) **(required)**: - `sortOrder` (number) **(required)**: - `createdAt` (string) **(required)**: - `updatedAt` (string) **(required)**: ### 400: Invalid request body ### 403: Only labs can update work trays ### 404: Tray not found ### 409: A tray with this code already exists ### 500: Internal server error ## Example ```bash curl -X PUT "https://api.guidelab.co/work-trays/{id}" \ -H "Authorization: Bearer gl_device_v1_" \ -H "Content-Type: application/json" \ -d '{ "code": "string", "color": "string", "description": "string", "isActive": true, "sortOrder": 0 }' ```