Share a private artifact with the confirmed organization
Owner only. JSON body { "accessType": "org_shared", "organizationId": "<current organization id>" } switches a private artifact to org_shared and sets organizationId to that id. The id must be the caller’s current membership. The only explicit row lock is the artifact. The organization foreign-key check takes an implicit KEY SHARE lock on the organization row. The update does not lock the user, the session, or membership rows. It re-checks membership and, for a session, that the session is still present and unexpired, in the conditional UPDATE. That statement is the linearization point. A different current organization at that snapshot is 409 ORGANIZATION_CHANGED and does not write. A membership removal, organization deletion, active-organization change, or session revocation that commits before the statement reads its rows returns 409, 400, or 401 UNAUTHENTICATED with no write. An authorization change that commits after that snapshot can land before the transaction commits and does not cancel the share. A deadlock, serialization failure, or lock timeout retries once and then returns 409 ORGANIZATION_CHANGED with no write. About 16 seconds is the budget for those two attempts, not a deadline for this endpoint. The update matches the id, the creator, and accessType private, so concurrent requests leave one organization-shared row. An artifact that is already org_shared returns 200 and does not change its organization, share token, or share password, for any confirmed organizationId and whether or not the caller has a current organization. This route does not create or remove a public share, and it does not change an organization-shared artifact back to private. Cookie-authenticated writes need Origin or Referer to be WEB_ORIGIN or PUBLIC_BASE_URL.
Factrove API key, usually prefixed ftrv_. Send Authorization: Bearer <key>. Product routes do not accept x-api-key as a credential. A present Authorization header that is not a valid key does not fall back to the session cookie.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Factrove","description":"Guides and references for Factrove, a self-hostable library for HTML artifacts.","colors":{"primary":"#5e64d6","light":"#858bee","dark":"#5055b6"},"api":{"openapi":"api-reference/openapi.json","examples":{"autogenerate":false}},"seo":{"metatags":{"canonical":"https://factrove.mintlify.app"}},"markdown":{"instructions":"Describe what the running code does. Do not invent hosted pricing, launch dates, or security guarantees. Share and viewer links are a configured base URL plus an artifact path. Show localhost and a placeholder origin such as https://library.example.com."},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"factrove","hasAudioNarration":false,"actualSubdomain":"factrove","customDomains":["docs.factrove.app"],"gitSource":{"type":"github","owner":"magnificode-ltd","repo":"factrove","deployBranch":"main","contentDirectory":"docs","isPrivate":true,"mountPath":"","label":"","_id":"6ad8f94f4e2c59229c394d72"},"entitlements":{},"buildId":"6af0674099ffa6db6966ee8e","clientVersion":"0.0.4088","searchFilterCounts":[{"language":"default","tag":"API reference","count":23},{"language":"default","tag":"Guides","count":10},{"language":"default","tag":"CLI reference","count":9},{"language":"default","tag":"Commands","count":9},{"language":"default","tag":"Artifacts","count":8},{"language":"default","tag":"Get started","count":6},{"language":"default","tag":"Auth","count":6},{"language":"default","tag":"Shares","count":4},{"language":"default","tag":"Public","count":3},{"language":"default","tag":"Overview","count":1}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization","slug":"/api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization","pageMetadata":{"title":"Share a private artifact with the confirmed organization","description":"Owner only. JSON body `{ \"accessType\": \"org_shared\", \"organizationId\": \"\u003ccurrent organization id>\" }` switches a private artifact to `org_shared` and sets `organizationId` to that id. The id must be the caller's current membership. The only explicit row lock is the artifact. The organization foreign-key check takes an implicit KEY SHARE lock on the organization row. The update does not lock the user, the session, or membership rows. It re-checks membership and, for a session, that the session is still present and unexpired, in the conditional UPDATE. That statement is the linearization point. A different current organization at that snapshot is `409 ORGANIZATION_CHANGED` and does not write. A membership removal, organization deletion, active-organization change, or session revocation that commits before the statement reads its rows returns 409, 400, or `401 UNAUTHENTICATED` with no write. An authorization change that commits after that snapshot can land before the transaction commits and does not cancel the share. A deadlock, serialization failure, or lock timeout retries once and then returns `409 ORGANIZATION_CHANGED` with no write. About 16 seconds is the budget for those two attempts, not a deadline for this endpoint. The update matches the id, the creator, and `accessType` private, so concurrent requests leave one organization-shared row. An artifact that is already `org_shared` returns 200 and does not change its organization, share token, or share password, for any confirmed organizationId and whether or not the caller has a current organization. This route does not create or remove a public share, and it does not change an organization-shared artifact back to private. Cookie-authenticated writes need Origin or Referer to be WEB_ORIGIN or PUBLIC_BASE_URL.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json patch /api/v1/artifacts/{id}","href":"/api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_components.p, {\n children: [\"Owner only. JSON body \", _jsx(_components.code, {\n children: \"{ \\\"accessType\\\": \\\"org_shared\\\", \\\"organizationId\\\": \\\"\u003ccurrent organization id>\\\" }\"\n }), \" switches a private artifact to \", _jsx(_components.code, {\n children: \"org_shared\"\n }), \" and sets \", _jsx(_components.code, {\n children: \"organizationId\"\n }), \" to that id. The id must be the caller’s current membership. The only explicit row lock is the artifact. The organization foreign-key check takes an implicit KEY SHARE lock on the organization row. The update does not lock the user, the session, or membership rows. It re-checks membership and, for a session, that the session is still present and unexpired, in the conditional UPDATE. That statement is the linearization point. A different current organization at that snapshot is \", _jsx(_components.code, {\n children: \"409 ORGANIZATION_CHANGED\"\n }), \" and does not write. A membership removal, organization deletion, active-organization change, or session revocation that commits before the statement reads its rows returns 409, 400, or \", _jsx(_components.code, {\n children: \"401 UNAUTHENTICATED\"\n }), \" with no write. An authorization change that commits after that snapshot can land before the transaction commits and does not cancel the share. A deadlock, serialization failure, or lock timeout retries once and then returns \", _jsx(_components.code, {\n children: \"409 ORGANIZATION_CHANGED\"\n }), \" with no write. About 16 seconds is the budget for those two attempts, not a deadline for this endpoint. The update matches the id, the creator, and \", _jsx(_components.code, {\n children: \"accessType\"\n }), \" private, so concurrent requests leave one organization-shared row. An artifact that is already \", _jsx(_components.code, {\n children: \"org_shared\"\n }), \" returns 200 and does not change its organization, share token, or share password, for any confirmed organizationId and whether or not the caller has a current organization. This route does not create or remove a public share, and it does not change an organization-shared artifact back to private. Cookie-authenticated writes need Origin or Referer to be WEB_ORIGIN or PUBLIC_BASE_URL.\"]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Share a private artifact with the confirmed organization","description":"Owner only. JSON body `{ \"accessType\": \"org_shared\", \"organizationId\": \"\u003ccurrent organization id>\" }` switches a private artifact to `org_shared` and sets `organizationId` to that id. The id must be the caller's current membership. The only explicit row lock is the artifact. The organization foreign-key check takes an implicit KEY SHARE lock on the organization row. The update does not lock the user, the session, or membership rows. It re-checks membership and, for a session, that the session is still present and unexpired, in the conditional UPDATE. That statement is the linearization point. A different current organization at that snapshot is `409 ORGANIZATION_CHANGED` and does not write. A membership removal, organization deletion, active-organization change, or session revocation that commits before the statement reads its rows returns 409, 400, or `401 UNAUTHENTICATED` with no write. An authorization change that commits after that snapshot can land before the transaction commits and does not cancel the share. A deadlock, serialization failure, or lock timeout retries once and then returns `409 ORGANIZATION_CHANGED` with no write. About 16 seconds is the budget for those two attempts, not a deadline for this endpoint. The update matches the id, the creator, and `accessType` private, so concurrent requests leave one organization-shared row. An artifact that is already `org_shared` returns 200 and does not change its organization, share token, or share password, for any confirmed organizationId and whether or not the caller has a current organization. This route does not create or remove a public share, and it does not change an organization-shared artifact back to private. Cookie-authenticated writes need Origin or Referer to be WEB_ORIGIN or PUBLIC_BASE_URL.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json patch /api/v1/artifacts/{id}","href":"/api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"operationId":"shareArtifactWithOrganization","tags":["Artifacts"],"summary":"Share a private artifact with the confirmed organization","description":"Owner only. JSON body `{ \"accessType\": \"org_shared\", \"organizationId\": \"\u003ccurrent organization id>\" }` switches a private artifact to `org_shared` and sets `organizationId` to that id. The id must be the caller's current membership. The only explicit row lock is the artifact. The organization foreign-key check takes an implicit KEY SHARE lock on the organization row. The update does not lock the user, the session, or membership rows. It re-checks membership and, for a session, that the session is still present and unexpired, in the conditional UPDATE. That statement is the linearization point. A different current organization at that snapshot is `409 ORGANIZATION_CHANGED` and does not write. A membership removal, organization deletion, active-organization change, or session revocation that commits before the statement reads its rows returns 409, 400, or `401 UNAUTHENTICATED` with no write. An authorization change that commits after that snapshot can land before the transaction commits and does not cancel the share. A deadlock, serialization failure, or lock timeout retries once and then returns `409 ORGANIZATION_CHANGED` with no write. About 16 seconds is the budget for those two attempts, not a deadline for this endpoint. The update matches the id, the creator, and `accessType` private, so concurrent requests leave one organization-shared row. An artifact that is already `org_shared` returns 200 and does not change its organization, share token, or share password, for any confirmed organizationId and whether or not the caller has a current organization. This route does not create or remove a public share, and it does not change an organization-shared artifact back to private. Cookie-authenticated writes need Origin or Referer to be WEB_ORIGIN or PUBLIC_BASE_URL.","security":["2003e698-8930-4518-b05b-e65c966dda1a","8dd4634e-c139-4b26-8407-8d13349511f0"],"parameters":["b203caa7-23f8-48fa-b3b6-a2437094d9fe"],"requestBody":"e302fc83-dd9c-4c7f-9c8e-718b3e936a60","responses":{"200":"f6ef6c43-096a-4e61-813b-b10b3d69b6ac","400":"aa53618b-506d-4cb8-b6f7-27b828ad1a23","401":"21ca467d-2dad-4d58-868f-f073f476e443","403":"18b26035-d3ac-45c2-955e-3c0ee36986bf","404":"7834c5b2-f933-49ab-8b51-431f00e3ee19","409":"35e92bd6-1b41-4d26-a496-78d5ef3640ea","413":"7ecbd80e-96ec-4b2f-8043-86e70b380d1d","500":"5e011466-c2e0-40f3-91f1-52853181af0e"},"method":"patch","type":"path","servers":["f7ed4e89-d556-412e-bb33-e97f0d376a70","36b86b74-9fdf-4f1e-a17c-f29f1f5c5c4d"],"path":"/api/v1/artifacts/{id}","baseUrlOptions":["http://localhost:3001","https://api.example.com"],"title":"Share a private artifact with the confirmed organization","codeSamples":[],"requiredOnlyExamples":false,"disableCodeSampleGeneration":true,"responseExampleType":"generated"},"dependencies":{"parameters":{"b203caa7-23f8-48fa-b3b6-a2437094d9fe":{"name":"id","in":"path","required":true,"description":"Artifact UUID.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","isRequired":true,"description":"Artifact UUID.","uniqueKey":"","typeLabel":"string\u003cuuid>"}}},"requestBody":{"required":true,"description":"Share the artifact with the organization the caller confirmed. That id must be the current membership.","content":{"application/json":{"schema":{"type":"object","properties":{"accessType":{"type":"string","const":"org_shared","isRequired":true,"uniqueKey":"accessType","typeLabel":"string"},"organizationId":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"organizationId","typeLabel":"string"}},"required":["accessType","organizationId"],"additionalProperties":false,"uniqueKey":"","typeLabel":"object"},"example":{"accessType":"org_shared","organizationId":"org_example"},"examples":{"Example":{"title":"Example","value":{"accessType":"org_shared","organizationId":"org_example"}}},"exampleType":"examples"}},"exampleType":"examples"},"responses":{"f6ef6c43-096a-4e61-813b-b10b3d69b6ac":{"description":"The artifact is org_shared. A repeat request for an artifact that is already org_shared returns it without writing, for any confirmed organizationId.","content":{"application/json":{"schema":{"type":"object","properties":{"artifact":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","isRequired":true,"uniqueKey":"artifact.id","typeLabel":"string\u003cuuid>"},"creatorUserId":{"type":"string","isRequired":true,"uniqueKey":"artifact.creatorUserId","typeLabel":"string"},"organizationId":{"oneOf":[{"type":"string","isRequired":true,"uniqueKey":"artifact.organizationId.oneOf.0","typeLabel":"string"},{"type":"null","isRequired":true,"uniqueKey":"artifact.organizationId.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"artifact.organizationId","typeLabel":"string | null"},"accessType":{"type":"string","enum":["private","org_shared"],"isRequired":true,"uniqueKey":"artifact.accessType","typeLabel":"enum\u003cstring>"},"filename":{"type":"string","isRequired":true,"uniqueKey":"artifact.filename","typeLabel":"string"},"name":{"oneOf":[{"type":"string","description":"Library name. Null when the artifact has no name.","maxLength":120,"minLength":1,"isRequired":true,"uniqueKey":"artifact.name.oneOf.0","typeLabel":"string"},{"type":"null","description":"Library name. Null when the artifact has no name.","isRequired":true,"uniqueKey":"artifact.name.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"artifact.name","typeLabel":"string | null"},"mimeType":{"type":"string","const":"text/html","isRequired":true,"uniqueKey":"artifact.mimeType","typeLabel":"string"},"sizeBytes":{"type":"integer","minimum":0,"maximum":9007199254740991,"isRequired":true,"uniqueKey":"artifact.sizeBytes","typeLabel":"integer"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","isRequired":true,"uniqueKey":"artifact.createdAt","typeLabel":"string\u003cdate-time>"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","isRequired":true,"uniqueKey":"artifact.updatedAt","typeLabel":"string\u003cdate-time>"},"uploadedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","isRequired":true,"uniqueKey":"artifact.uploadedAt","typeLabel":"string\u003cdate-time>"},"viewerUrl":{"type":"string","format":"uri","isRequired":true,"uniqueKey":"artifact.viewerUrl","typeLabel":"string\u003curi>"},"contentUrl":{"type":"string","format":"uri","isRequired":true,"uniqueKey":"artifact.contentUrl","typeLabel":"string\u003curi>"},"shared":{"type":"boolean","isRequired":true,"uniqueKey":"artifact.shared","typeLabel":"boolean"},"passwordProtected":{"type":"boolean","isRequired":true,"uniqueKey":"artifact.passwordProtected","typeLabel":"boolean"}},"required":["id","creatorUserId","organizationId","accessType","filename","name","mimeType","sizeBytes","createdAt","updatedAt","uploadedAt","viewerUrl","contentUrl","shared","passwordProtected"],"additionalProperties":false,"isRequired":true,"uniqueKey":"artifact","typeLabel":"object"}},"required":["artifact"],"additionalProperties":false,"uniqueKey":"","typeLabel":"object"},"example":{"artifact":{"id":"11111111-1111-4111-8111-111111111111","creatorUserId":"user_example","organizationId":"org_example","accessType":"org_shared","filename":"11111111-1111-4111-8111-111111111111.html","name":"hello","mimeType":"text/html","sizeBytes":527,"createdAt":"2026-10-21T12:00:00.000Z","updatedAt":"2026-10-21T12:00:00.000Z","uploadedAt":"2026-10-21T12:00:00.000Z","viewerUrl":"http://localhost:3000/artifacts/11111111-1111-4111-8111-111111111111","contentUrl":"http://localhost:3001/api/v1/artifacts/11111111-1111-4111-8111-111111111111/content","shared":false,"passwordProtected":false}},"examples":{"Example":{"title":"Example","value":{"artifact":{"id":"11111111-1111-4111-8111-111111111111","creatorUserId":"user_example","organizationId":"org_example","accessType":"org_shared","filename":"11111111-1111-4111-8111-111111111111.html","name":"hello","mimeType":"text/html","sizeBytes":527,"createdAt":"2026-10-21T12:00:00.000Z","updatedAt":"2026-10-21T12:00:00.000Z","uploadedAt":"2026-10-21T12:00:00.000Z","viewerUrl":"http://localhost:3000/artifacts/11111111-1111-4111-8111-111111111111","contentUrl":"http://localhost:3001/api/v1/artifacts/11111111-1111-4111-8111-111111111111/content","shared":false,"passwordProtected":false}}}},"exampleType":"examples"}},"exampleType":"examples"},"aa53618b-506d-4cb8-b6f7-27b828ad1a23":{"description":"This route shares a private artifact with the confirmed organization. A JSON array, and a JSON object with any other shape, including accessType private or a missing organizationId, is `400 INVALID_REQUEST` with message `Send { \"accessType\": \"org_shared\", \"organizationId\": \"\u003ccurrent organization id>\" }. This shares a private artifact with that organization.` Malformed JSON, null, and JSON primitives are `400 INVALID_REQUEST` with message `The request is invalid.` A body whose media type is not application/json is `400 INVALID_REQUEST` with message `Send JSON with Content-Type application/json.` A private artifact and no current organization is `400 ORGANIZATION_REQUIRED` and the row stays private. An id that is not a UUID is also `400 INVALID_REQUEST`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"additionalProperties":false,"properties":{"code":{"type":"string","enum":["INVALID_REQUEST","ORGANIZATION_REQUIRED","ORGANIZATION_CHANGED","UNAUTHENTICATED","PASSWORD_REQUIRED","PASSWORD_INCORRECT","FORBIDDEN","ARTIFACT_NOT_FOUND","CONTENT_CONFLICT","FILE_TOO_LARGE","CONTENT_TOO_LARGE","UNSUPPORTED_FILE_TYPE","CONTENT_TOO_COMPLEX","RATE_LIMITED","INTERNAL_ERROR","STORAGE_UNAVAILABLE","CONVERSION_UNAVAILABLE","UNLOCK_UNAVAILABLE"],"description":"400/404 INVALID_REQUEST: The request is missing a required field, has the wrong shape, or failed validation. Typical causes are a missing file, an invalid access type, view, format, or artifact id, or invalid UTF-8. Unmatched non-public product routes also return 404 INVALID_REQUEST with message Not found. 400 ORGANIZATION_REQUIRED: The caller asked to share with an organization but has no current organization membership. Upload with accessType org_shared and PATCH /api/v1/artifacts/{id} for a private artifact both use this code. 409 ORGANIZATION_CHANGED: PATCH /api/v1/artifacts/{id} for a private artifact named an organizationId that is not the caller's current membership when the conditional UPDATE reads, or a deadlock, serialization failure, or lock timeout persisted after one retry. The artifact is not written. That UPDATE is the linearization point: an authorization change that commits after its snapshot can land before commit and does not cancel the share. About 16 seconds is the budget for the two attempts, not an endpoint deadline. An artifact that is already org_shared returns 200 instead. 401 UNAUTHENTICATED: The product route needs a session cookie or Authorization: Bearer API key, and neither was accepted. PATCH /api/v1/artifacts/{id} also returns this when the session was revoked or expired before the conditional update read it, and does not write. A revocation that commits after that snapshot does not cancel the share. 401 PASSWORD_REQUIRED: The public share is password protected and the request did not present a valid unlock grant or content ticket. 401 PASSWORD_INCORRECT: The password sent to the public unlock route did not match. 403 FORBIDDEN: A cookie-authenticated write used an Origin or Referer that is not WEB_ORIGIN or PUBLIC_BASE_URL. 404 ARTIFACT_NOT_FOUND: The artifact id is unknown, the caller cannot read it, or the public share token is not active. Rename and delete also use this body when the caller is not the creator, including an organization admin or another member who can read an org_shared artifact. Those cases share this body. 409 CONTENT_CONFLICT: Another replace of the same artifact revision finished first. Upload again to replace the current content. Delete returns this code when concurrent replaces prevent deletion after eight attempts. Retry DELETE. 413 FILE_TOO_LARGE: The upload is larger than the 10 MiB HTML limit. A JSON body larger than 102,400 bytes uses the same code with message The request is too large. 413 CONTENT_TOO_LARGE: Stored HTML is larger than the Markdown conversion input limit. 415 UNSUPPORTED_FILE_TYPE: The upload is not a .html or .htm file. 422 CONTENT_TOO_COMPLEX: Markdown conversion exceeded its time, memory, nesting, or output limit. 429 RATE_LIMITED: Too many public views from one client address, or too many password attempts. Password-attempt 429 responses include Retry-After. Public-view 429 responses do not. 500 INTERNAL_ERROR: An unexpected persistence or service failure. 503 STORAGE_UNAVAILABLE: Object storage failed. A failed upload leaves no artifact row. A failed artifact delete keeps the row. The object may already be gone, so retry DELETE. 503 CONVERSION_UNAVAILABLE: The Markdown conversion worker pool is full. This response does not include Retry-After. 503 UNLOCK_UNAVAILABLE: Password verification is busy because the process-wide Argon2 gate is saturated or every remaining share check slot is in flight. Includes Retry-After.","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"}},"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"additionalProperties":false,"description":"Product error envelope. Better Auth `/api/auth` routes may return a different JSON shape.","uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"INVALID_REQUEST","message":"Artifact id must be a UUID."}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"INVALID_REQUEST","message":"Artifact id must be a UUID."}}}},"exampleType":"examples"}},"exampleType":"examples"},"21ca467d-2dad-4d58-868f-f073f476e443":{"description":"Missing credentials, or a session that was revoked or expired before the conditional update read it. Code `UNAUTHENTICATED`. The artifact is not written. A revocation that commits after that snapshot does not cancel a share the statement already accepted.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"additionalProperties":false,"properties":{"code":{"type":"string","enum":["INVALID_REQUEST","ORGANIZATION_REQUIRED","ORGANIZATION_CHANGED","UNAUTHENTICATED","PASSWORD_REQUIRED","PASSWORD_INCORRECT","FORBIDDEN","ARTIFACT_NOT_FOUND","CONTENT_CONFLICT","FILE_TOO_LARGE","CONTENT_TOO_LARGE","UNSUPPORTED_FILE_TYPE","CONTENT_TOO_COMPLEX","RATE_LIMITED","INTERNAL_ERROR","STORAGE_UNAVAILABLE","CONVERSION_UNAVAILABLE","UNLOCK_UNAVAILABLE"],"description":"400/404 INVALID_REQUEST: The request is missing a required field, has the wrong shape, or failed validation. Typical causes are a missing file, an invalid access type, view, format, or artifact id, or invalid UTF-8. Unmatched non-public product routes also return 404 INVALID_REQUEST with message Not found. 400 ORGANIZATION_REQUIRED: The caller asked to share with an organization but has no current organization membership. Upload with accessType org_shared and PATCH /api/v1/artifacts/{id} for a private artifact both use this code. 409 ORGANIZATION_CHANGED: PATCH /api/v1/artifacts/{id} for a private artifact named an organizationId that is not the caller's current membership when the conditional UPDATE reads, or a deadlock, serialization failure, or lock timeout persisted after one retry. The artifact is not written. That UPDATE is the linearization point: an authorization change that commits after its snapshot can land before commit and does not cancel the share. About 16 seconds is the budget for the two attempts, not an endpoint deadline. An artifact that is already org_shared returns 200 instead. 401 UNAUTHENTICATED: The product route needs a session cookie or Authorization: Bearer API key, and neither was accepted. PATCH /api/v1/artifacts/{id} also returns this when the session was revoked or expired before the conditional update read it, and does not write. A revocation that commits after that snapshot does not cancel the share. 401 PASSWORD_REQUIRED: The public share is password protected and the request did not present a valid unlock grant or content ticket. 401 PASSWORD_INCORRECT: The password sent to the public unlock route did not match. 403 FORBIDDEN: A cookie-authenticated write used an Origin or Referer that is not WEB_ORIGIN or PUBLIC_BASE_URL. 404 ARTIFACT_NOT_FOUND: The artifact id is unknown, the caller cannot read it, or the public share token is not active. Rename and delete also use this body when the caller is not the creator, including an organization admin or another member who can read an org_shared artifact. Those cases share this body. 409 CONTENT_CONFLICT: Another replace of the same artifact revision finished first. Upload again to replace the current content. Delete returns this code when concurrent replaces prevent deletion after eight attempts. Retry DELETE. 413 FILE_TOO_LARGE: The upload is larger than the 10 MiB HTML limit. A JSON body larger than 102,400 bytes uses the same code with message The request is too large. 413 CONTENT_TOO_LARGE: Stored HTML is larger than the Markdown conversion input limit. 415 UNSUPPORTED_FILE_TYPE: The upload is not a .html or .htm file. 422 CONTENT_TOO_COMPLEX: Markdown conversion exceeded its time, memory, nesting, or output limit. 429 RATE_LIMITED: Too many public views from one client address, or too many password attempts. Password-attempt 429 responses include Retry-After. Public-view 429 responses do not. 500 INTERNAL_ERROR: An unexpected persistence or service failure. 503 STORAGE_UNAVAILABLE: Object storage failed. A failed upload leaves no artifact row. A failed artifact delete keeps the row. The object may already be gone, so retry DELETE. 503 CONVERSION_UNAVAILABLE: The Markdown conversion worker pool is full. This response does not include Retry-After. 503 UNLOCK_UNAVAILABLE: Password verification is busy because the process-wide Argon2 gate is saturated or every remaining share check slot is in flight. Includes Retry-After.","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"}},"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"additionalProperties":false,"description":"Product error envelope. Better Auth `/api/auth` routes may return a different JSON shape.","uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"UNAUTHENTICATED","message":"Sign in to continue."}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"UNAUTHENTICATED","message":"Sign in to continue."}}}},"exampleType":"examples"}},"exampleType":"examples"},"18b26035-d3ac-45c2-955e-3c0ee36986bf":{"description":"Cookie write from a disallowed origin. Code `FORBIDDEN`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"additionalProperties":false,"properties":{"code":{"type":"string","enum":["INVALID_REQUEST","ORGANIZATION_REQUIRED","ORGANIZATION_CHANGED","UNAUTHENTICATED","PASSWORD_REQUIRED","PASSWORD_INCORRECT","FORBIDDEN","ARTIFACT_NOT_FOUND","CONTENT_CONFLICT","FILE_TOO_LARGE","CONTENT_TOO_LARGE","UNSUPPORTED_FILE_TYPE","CONTENT_TOO_COMPLEX","RATE_LIMITED","INTERNAL_ERROR","STORAGE_UNAVAILABLE","CONVERSION_UNAVAILABLE","UNLOCK_UNAVAILABLE"],"description":"400/404 INVALID_REQUEST: The request is missing a required field, has the wrong shape, or failed validation. Typical causes are a missing file, an invalid access type, view, format, or artifact id, or invalid UTF-8. Unmatched non-public product routes also return 404 INVALID_REQUEST with message Not found. 400 ORGANIZATION_REQUIRED: The caller asked to share with an organization but has no current organization membership. Upload with accessType org_shared and PATCH /api/v1/artifacts/{id} for a private artifact both use this code. 409 ORGANIZATION_CHANGED: PATCH /api/v1/artifacts/{id} for a private artifact named an organizationId that is not the caller's current membership when the conditional UPDATE reads, or a deadlock, serialization failure, or lock timeout persisted after one retry. The artifact is not written. That UPDATE is the linearization point: an authorization change that commits after its snapshot can land before commit and does not cancel the share. About 16 seconds is the budget for the two attempts, not an endpoint deadline. An artifact that is already org_shared returns 200 instead. 401 UNAUTHENTICATED: The product route needs a session cookie or Authorization: Bearer API key, and neither was accepted. PATCH /api/v1/artifacts/{id} also returns this when the session was revoked or expired before the conditional update read it, and does not write. A revocation that commits after that snapshot does not cancel the share. 401 PASSWORD_REQUIRED: The public share is password protected and the request did not present a valid unlock grant or content ticket. 401 PASSWORD_INCORRECT: The password sent to the public unlock route did not match. 403 FORBIDDEN: A cookie-authenticated write used an Origin or Referer that is not WEB_ORIGIN or PUBLIC_BASE_URL. 404 ARTIFACT_NOT_FOUND: The artifact id is unknown, the caller cannot read it, or the public share token is not active. Rename and delete also use this body when the caller is not the creator, including an organization admin or another member who can read an org_shared artifact. Those cases share this body. 409 CONTENT_CONFLICT: Another replace of the same artifact revision finished first. Upload again to replace the current content. Delete returns this code when concurrent replaces prevent deletion after eight attempts. Retry DELETE. 413 FILE_TOO_LARGE: The upload is larger than the 10 MiB HTML limit. A JSON body larger than 102,400 bytes uses the same code with message The request is too large. 413 CONTENT_TOO_LARGE: Stored HTML is larger than the Markdown conversion input limit. 415 UNSUPPORTED_FILE_TYPE: The upload is not a .html or .htm file. 422 CONTENT_TOO_COMPLEX: Markdown conversion exceeded its time, memory, nesting, or output limit. 429 RATE_LIMITED: Too many public views from one client address, or too many password attempts. Password-attempt 429 responses include Retry-After. Public-view 429 responses do not. 500 INTERNAL_ERROR: An unexpected persistence or service failure. 503 STORAGE_UNAVAILABLE: Object storage failed. A failed upload leaves no artifact row. A failed artifact delete keeps the row. The object may already be gone, so retry DELETE. 503 CONVERSION_UNAVAILABLE: The Markdown conversion worker pool is full. This response does not include Retry-After. 503 UNLOCK_UNAVAILABLE: Password verification is busy because the process-wide Argon2 gate is saturated or every remaining share check slot is in flight. Includes Retry-After.","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"}},"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"additionalProperties":false,"description":"Product error envelope. Better Auth `/api/auth` routes may return a different JSON shape.","uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"FORBIDDEN","message":"This request origin is not allowed."}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"FORBIDDEN","message":"This request origin is not allowed."}}}},"exampleType":"examples"}},"exampleType":"examples"},"7834c5b2-f933-49ab-8b51-431f00e3ee19":{"description":"Unknown artifact, or the caller is not the owner. Code `ARTIFACT_NOT_FOUND`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"additionalProperties":false,"properties":{"code":{"type":"string","enum":["INVALID_REQUEST","ORGANIZATION_REQUIRED","ORGANIZATION_CHANGED","UNAUTHENTICATED","PASSWORD_REQUIRED","PASSWORD_INCORRECT","FORBIDDEN","ARTIFACT_NOT_FOUND","CONTENT_CONFLICT","FILE_TOO_LARGE","CONTENT_TOO_LARGE","UNSUPPORTED_FILE_TYPE","CONTENT_TOO_COMPLEX","RATE_LIMITED","INTERNAL_ERROR","STORAGE_UNAVAILABLE","CONVERSION_UNAVAILABLE","UNLOCK_UNAVAILABLE"],"description":"400/404 INVALID_REQUEST: The request is missing a required field, has the wrong shape, or failed validation. Typical causes are a missing file, an invalid access type, view, format, or artifact id, or invalid UTF-8. Unmatched non-public product routes also return 404 INVALID_REQUEST with message Not found. 400 ORGANIZATION_REQUIRED: The caller asked to share with an organization but has no current organization membership. Upload with accessType org_shared and PATCH /api/v1/artifacts/{id} for a private artifact both use this code. 409 ORGANIZATION_CHANGED: PATCH /api/v1/artifacts/{id} for a private artifact named an organizationId that is not the caller's current membership when the conditional UPDATE reads, or a deadlock, serialization failure, or lock timeout persisted after one retry. The artifact is not written. That UPDATE is the linearization point: an authorization change that commits after its snapshot can land before commit and does not cancel the share. About 16 seconds is the budget for the two attempts, not an endpoint deadline. An artifact that is already org_shared returns 200 instead. 401 UNAUTHENTICATED: The product route needs a session cookie or Authorization: Bearer API key, and neither was accepted. PATCH /api/v1/artifacts/{id} also returns this when the session was revoked or expired before the conditional update read it, and does not write. A revocation that commits after that snapshot does not cancel the share. 401 PASSWORD_REQUIRED: The public share is password protected and the request did not present a valid unlock grant or content ticket. 401 PASSWORD_INCORRECT: The password sent to the public unlock route did not match. 403 FORBIDDEN: A cookie-authenticated write used an Origin or Referer that is not WEB_ORIGIN or PUBLIC_BASE_URL. 404 ARTIFACT_NOT_FOUND: The artifact id is unknown, the caller cannot read it, or the public share token is not active. Rename and delete also use this body when the caller is not the creator, including an organization admin or another member who can read an org_shared artifact. Those cases share this body. 409 CONTENT_CONFLICT: Another replace of the same artifact revision finished first. Upload again to replace the current content. Delete returns this code when concurrent replaces prevent deletion after eight attempts. Retry DELETE. 413 FILE_TOO_LARGE: The upload is larger than the 10 MiB HTML limit. A JSON body larger than 102,400 bytes uses the same code with message The request is too large. 413 CONTENT_TOO_LARGE: Stored HTML is larger than the Markdown conversion input limit. 415 UNSUPPORTED_FILE_TYPE: The upload is not a .html or .htm file. 422 CONTENT_TOO_COMPLEX: Markdown conversion exceeded its time, memory, nesting, or output limit. 429 RATE_LIMITED: Too many public views from one client address, or too many password attempts. Password-attempt 429 responses include Retry-After. Public-view 429 responses do not. 500 INTERNAL_ERROR: An unexpected persistence or service failure. 503 STORAGE_UNAVAILABLE: Object storage failed. A failed upload leaves no artifact row. A failed artifact delete keeps the row. The object may already be gone, so retry DELETE. 503 CONVERSION_UNAVAILABLE: The Markdown conversion worker pool is full. This response does not include Retry-After. 503 UNLOCK_UNAVAILABLE: Password verification is busy because the process-wide Argon2 gate is saturated or every remaining share check slot is in flight. Includes Retry-After.","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"}},"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"additionalProperties":false,"description":"Product error envelope. Better Auth `/api/auth` routes may return a different JSON shape.","uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"ARTIFACT_NOT_FOUND","message":"Artifact was not found."}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"ARTIFACT_NOT_FOUND","message":"Artifact was not found."}}}},"exampleType":"examples"}},"exampleType":"examples"},"35e92bd6-1b41-4d26-a496-78d5ef3640ea":{"description":"The artifact is still private and organizationId is not the caller's current membership when the conditional update reads, or a deadlock, serialization failure, or lock timeout persisted after one retry. Code `ORGANIZATION_CHANGED`. The artifact is not written. An authorization change that commits after that snapshot does not produce this response and does not undo the share. About 16 seconds is the budget for the two attempts, not an endpoint deadline.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"additionalProperties":false,"properties":{"code":{"type":"string","enum":["INVALID_REQUEST","ORGANIZATION_REQUIRED","ORGANIZATION_CHANGED","UNAUTHENTICATED","PASSWORD_REQUIRED","PASSWORD_INCORRECT","FORBIDDEN","ARTIFACT_NOT_FOUND","CONTENT_CONFLICT","FILE_TOO_LARGE","CONTENT_TOO_LARGE","UNSUPPORTED_FILE_TYPE","CONTENT_TOO_COMPLEX","RATE_LIMITED","INTERNAL_ERROR","STORAGE_UNAVAILABLE","CONVERSION_UNAVAILABLE","UNLOCK_UNAVAILABLE"],"description":"400/404 INVALID_REQUEST: The request is missing a required field, has the wrong shape, or failed validation. Typical causes are a missing file, an invalid access type, view, format, or artifact id, or invalid UTF-8. Unmatched non-public product routes also return 404 INVALID_REQUEST with message Not found. 400 ORGANIZATION_REQUIRED: The caller asked to share with an organization but has no current organization membership. Upload with accessType org_shared and PATCH /api/v1/artifacts/{id} for a private artifact both use this code. 409 ORGANIZATION_CHANGED: PATCH /api/v1/artifacts/{id} for a private artifact named an organizationId that is not the caller's current membership when the conditional UPDATE reads, or a deadlock, serialization failure, or lock timeout persisted after one retry. The artifact is not written. That UPDATE is the linearization point: an authorization change that commits after its snapshot can land before commit and does not cancel the share. About 16 seconds is the budget for the two attempts, not an endpoint deadline. An artifact that is already org_shared returns 200 instead. 401 UNAUTHENTICATED: The product route needs a session cookie or Authorization: Bearer API key, and neither was accepted. PATCH /api/v1/artifacts/{id} also returns this when the session was revoked or expired before the conditional update read it, and does not write. A revocation that commits after that snapshot does not cancel the share. 401 PASSWORD_REQUIRED: The public share is password protected and the request did not present a valid unlock grant or content ticket. 401 PASSWORD_INCORRECT: The password sent to the public unlock route did not match. 403 FORBIDDEN: A cookie-authenticated write used an Origin or Referer that is not WEB_ORIGIN or PUBLIC_BASE_URL. 404 ARTIFACT_NOT_FOUND: The artifact id is unknown, the caller cannot read it, or the public share token is not active. Rename and delete also use this body when the caller is not the creator, including an organization admin or another member who can read an org_shared artifact. Those cases share this body. 409 CONTENT_CONFLICT: Another replace of the same artifact revision finished first. Upload again to replace the current content. Delete returns this code when concurrent replaces prevent deletion after eight attempts. Retry DELETE. 413 FILE_TOO_LARGE: The upload is larger than the 10 MiB HTML limit. A JSON body larger than 102,400 bytes uses the same code with message The request is too large. 413 CONTENT_TOO_LARGE: Stored HTML is larger than the Markdown conversion input limit. 415 UNSUPPORTED_FILE_TYPE: The upload is not a .html or .htm file. 422 CONTENT_TOO_COMPLEX: Markdown conversion exceeded its time, memory, nesting, or output limit. 429 RATE_LIMITED: Too many public views from one client address, or too many password attempts. Password-attempt 429 responses include Retry-After. Public-view 429 responses do not. 500 INTERNAL_ERROR: An unexpected persistence or service failure. 503 STORAGE_UNAVAILABLE: Object storage failed. A failed upload leaves no artifact row. A failed artifact delete keeps the row. The object may already be gone, so retry DELETE. 503 CONVERSION_UNAVAILABLE: The Markdown conversion worker pool is full. This response does not include Retry-After. 503 UNLOCK_UNAVAILABLE: Password verification is busy because the process-wide Argon2 gate is saturated or every remaining share check slot is in flight. Includes Retry-After.","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"}},"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"additionalProperties":false,"description":"Product error envelope. Better Auth `/api/auth` routes may return a different JSON shape.","uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"ORGANIZATION_CHANGED","message":"The current organization changed. Confirm the organization and try again."}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"ORGANIZATION_CHANGED","message":"The current organization changed. Confirm the organization and try again."}}}},"exampleType":"examples"}},"exampleType":"examples"},"7ecbd80e-96ec-4b2f-8043-86e70b380d1d":{"description":"The JSON body is larger than 102,400 bytes. Code `FILE_TOO_LARGE` with message `The request is too large.`","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"additionalProperties":false,"properties":{"code":{"type":"string","enum":["INVALID_REQUEST","ORGANIZATION_REQUIRED","ORGANIZATION_CHANGED","UNAUTHENTICATED","PASSWORD_REQUIRED","PASSWORD_INCORRECT","FORBIDDEN","ARTIFACT_NOT_FOUND","CONTENT_CONFLICT","FILE_TOO_LARGE","CONTENT_TOO_LARGE","UNSUPPORTED_FILE_TYPE","CONTENT_TOO_COMPLEX","RATE_LIMITED","INTERNAL_ERROR","STORAGE_UNAVAILABLE","CONVERSION_UNAVAILABLE","UNLOCK_UNAVAILABLE"],"description":"400/404 INVALID_REQUEST: The request is missing a required field, has the wrong shape, or failed validation. Typical causes are a missing file, an invalid access type, view, format, or artifact id, or invalid UTF-8. Unmatched non-public product routes also return 404 INVALID_REQUEST with message Not found. 400 ORGANIZATION_REQUIRED: The caller asked to share with an organization but has no current organization membership. Upload with accessType org_shared and PATCH /api/v1/artifacts/{id} for a private artifact both use this code. 409 ORGANIZATION_CHANGED: PATCH /api/v1/artifacts/{id} for a private artifact named an organizationId that is not the caller's current membership when the conditional UPDATE reads, or a deadlock, serialization failure, or lock timeout persisted after one retry. The artifact is not written. That UPDATE is the linearization point: an authorization change that commits after its snapshot can land before commit and does not cancel the share. About 16 seconds is the budget for the two attempts, not an endpoint deadline. An artifact that is already org_shared returns 200 instead. 401 UNAUTHENTICATED: The product route needs a session cookie or Authorization: Bearer API key, and neither was accepted. PATCH /api/v1/artifacts/{id} also returns this when the session was revoked or expired before the conditional update read it, and does not write. A revocation that commits after that snapshot does not cancel the share. 401 PASSWORD_REQUIRED: The public share is password protected and the request did not present a valid unlock grant or content ticket. 401 PASSWORD_INCORRECT: The password sent to the public unlock route did not match. 403 FORBIDDEN: A cookie-authenticated write used an Origin or Referer that is not WEB_ORIGIN or PUBLIC_BASE_URL. 404 ARTIFACT_NOT_FOUND: The artifact id is unknown, the caller cannot read it, or the public share token is not active. Rename and delete also use this body when the caller is not the creator, including an organization admin or another member who can read an org_shared artifact. Those cases share this body. 409 CONTENT_CONFLICT: Another replace of the same artifact revision finished first. Upload again to replace the current content. Delete returns this code when concurrent replaces prevent deletion after eight attempts. Retry DELETE. 413 FILE_TOO_LARGE: The upload is larger than the 10 MiB HTML limit. A JSON body larger than 102,400 bytes uses the same code with message The request is too large. 413 CONTENT_TOO_LARGE: Stored HTML is larger than the Markdown conversion input limit. 415 UNSUPPORTED_FILE_TYPE: The upload is not a .html or .htm file. 422 CONTENT_TOO_COMPLEX: Markdown conversion exceeded its time, memory, nesting, or output limit. 429 RATE_LIMITED: Too many public views from one client address, or too many password attempts. Password-attempt 429 responses include Retry-After. Public-view 429 responses do not. 500 INTERNAL_ERROR: An unexpected persistence or service failure. 503 STORAGE_UNAVAILABLE: Object storage failed. A failed upload leaves no artifact row. A failed artifact delete keeps the row. The object may already be gone, so retry DELETE. 503 CONVERSION_UNAVAILABLE: The Markdown conversion worker pool is full. This response does not include Retry-After. 503 UNLOCK_UNAVAILABLE: Password verification is busy because the process-wide Argon2 gate is saturated or every remaining share check slot is in flight. Includes Retry-After.","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"}},"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"additionalProperties":false,"description":"Product error envelope. Better Auth `/api/auth` routes may return a different JSON shape.","uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"FILE_TOO_LARGE","message":"The request is too large."}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"FILE_TOO_LARGE","message":"The request is too large."}}}},"exampleType":"examples"}},"exampleType":"examples"},"5e011466-c2e0-40f3-91f1-52853181af0e":{"description":"JSON error envelope `{ error: { code, message } }`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"additionalProperties":false,"properties":{"code":{"type":"string","enum":["INVALID_REQUEST","ORGANIZATION_REQUIRED","ORGANIZATION_CHANGED","UNAUTHENTICATED","PASSWORD_REQUIRED","PASSWORD_INCORRECT","FORBIDDEN","ARTIFACT_NOT_FOUND","CONTENT_CONFLICT","FILE_TOO_LARGE","CONTENT_TOO_LARGE","UNSUPPORTED_FILE_TYPE","CONTENT_TOO_COMPLEX","RATE_LIMITED","INTERNAL_ERROR","STORAGE_UNAVAILABLE","CONVERSION_UNAVAILABLE","UNLOCK_UNAVAILABLE"],"description":"400/404 INVALID_REQUEST: The request is missing a required field, has the wrong shape, or failed validation. Typical causes are a missing file, an invalid access type, view, format, or artifact id, or invalid UTF-8. Unmatched non-public product routes also return 404 INVALID_REQUEST with message Not found. 400 ORGANIZATION_REQUIRED: The caller asked to share with an organization but has no current organization membership. Upload with accessType org_shared and PATCH /api/v1/artifacts/{id} for a private artifact both use this code. 409 ORGANIZATION_CHANGED: PATCH /api/v1/artifacts/{id} for a private artifact named an organizationId that is not the caller's current membership when the conditional UPDATE reads, or a deadlock, serialization failure, or lock timeout persisted after one retry. The artifact is not written. That UPDATE is the linearization point: an authorization change that commits after its snapshot can land before commit and does not cancel the share. About 16 seconds is the budget for the two attempts, not an endpoint deadline. An artifact that is already org_shared returns 200 instead. 401 UNAUTHENTICATED: The product route needs a session cookie or Authorization: Bearer API key, and neither was accepted. PATCH /api/v1/artifacts/{id} also returns this when the session was revoked or expired before the conditional update read it, and does not write. A revocation that commits after that snapshot does not cancel the share. 401 PASSWORD_REQUIRED: The public share is password protected and the request did not present a valid unlock grant or content ticket. 401 PASSWORD_INCORRECT: The password sent to the public unlock route did not match. 403 FORBIDDEN: A cookie-authenticated write used an Origin or Referer that is not WEB_ORIGIN or PUBLIC_BASE_URL. 404 ARTIFACT_NOT_FOUND: The artifact id is unknown, the caller cannot read it, or the public share token is not active. Rename and delete also use this body when the caller is not the creator, including an organization admin or another member who can read an org_shared artifact. Those cases share this body. 409 CONTENT_CONFLICT: Another replace of the same artifact revision finished first. Upload again to replace the current content. Delete returns this code when concurrent replaces prevent deletion after eight attempts. Retry DELETE. 413 FILE_TOO_LARGE: The upload is larger than the 10 MiB HTML limit. A JSON body larger than 102,400 bytes uses the same code with message The request is too large. 413 CONTENT_TOO_LARGE: Stored HTML is larger than the Markdown conversion input limit. 415 UNSUPPORTED_FILE_TYPE: The upload is not a .html or .htm file. 422 CONTENT_TOO_COMPLEX: Markdown conversion exceeded its time, memory, nesting, or output limit. 429 RATE_LIMITED: Too many public views from one client address, or too many password attempts. Password-attempt 429 responses include Retry-After. Public-view 429 responses do not. 500 INTERNAL_ERROR: An unexpected persistence or service failure. 503 STORAGE_UNAVAILABLE: Object storage failed. A failed upload leaves no artifact row. A failed artifact delete keeps the row. The object may already be gone, so retry DELETE. 503 CONVERSION_UNAVAILABLE: The Markdown conversion worker pool is full. This response does not include Retry-After. 503 UNLOCK_UNAVAILABLE: Password verification is busy because the process-wide Argon2 gate is saturated or every remaining share check slot is in flight. Includes Retry-After.","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"}},"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"additionalProperties":false,"description":"Product error envelope. Better Auth `/api/auth` routes may return a different JSON shape.","uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"INTERNAL_ERROR","message":"An unexpected error occurred."}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"INTERNAL_ERROR","message":"An unexpected error occurred."}}}},"exampleType":"examples"}},"exampleType":"examples"}},"security":{"2003e698-8930-4518-b05b-e65c966dda1a":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Factrove API key, usually prefixed `ftrv_`. Send `Authorization: Bearer \u003ckey>`. Product routes do not accept `x-api-key` as a credential. A present Authorization header that is not a valid key does not fall back to the session cookie.","scopes":[],"schemeName":"bearerAuth"}},"8dd4634e-c139-4b26-8407-8d13349511f0":{"sessionCookie":{"type":"apiKey","in":"cookie","name":"better-auth.session_token","description":"Better Auth session cookie from email/password sign-in. On an https API origin the name is `__Secure-better-auth.session_token`. On http it is `better-auth.session_token`. Host-only unless AUTH_COOKIE_DOMAIN is set. Use a cookie jar instead of typing the name.","scopes":[],"schemeName":"sessionCookie"}}},"servers":{"f7ed4e89-d556-412e-bb33-e97f0d376a70":{"url":"http://localhost:3001","description":"Local development API origin"},"36b86b74-9fdf-4f1e-a17c-f29f1f5c5c4d":{"url":"https://api.example.com","description":"Example self-hosted API origin"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","description":"Factrove API key, usually prefixed `ftrv_`. Send `Authorization: Bearer \u003ckey>`. Product routes do not accept `x-api-key` as a credential. A present Authorization header that is not a valid key does not fall back to the session cookie.","scopes":[],"schemeName":"bearerAuth"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"Factrove API key, usually prefixed `ftrv_`. Send `Authorization: Bearer \u003ckey>`. Product routes do not accept `x-api-key` as a credential. A present Authorization header that is not a valid key does not fall back to the session cookie.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"bearerAuth","name":"Authorization"}],"title":"bearerAuth"},{"schemes":[{"scheme":{"type":"apiKey","in":"cookie","name":"better-auth.session_token","description":"Better Auth session cookie from email/password sign-in. On an https API origin the name is `__Secure-better-auth.session_token`. On http it is `better-auth.session_token`. Host-only unless AUTH_COOKIE_DOMAIN is set. Use a cookie jar instead of typing the name.","scopes":[],"schemeName":"sessionCookie"},"schema":{"title":"better-auth.session_token","type":"string","description":"Better Auth session cookie from email/password sign-in. On an https API origin the name is `__Secure-better-auth.session_token`. On http it is `better-auth.session_token`. Host-only unless AUTH_COOKIE_DOMAIN is set. Use a cookie jar instead of typing the name.","isRequired":true,"typeLabel":"string","deprecated":false},"schemeName":"sessionCookie","name":"better-auth.session_token"}],"title":"sessionCookie"}]},"originalFileLocation":"api-reference/openapi.json"},"subdomain":"factrove","siteName":"Factrove","title":"Share a private artifact with the confirmed organization - Factrove","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-07T10:02:38.509Z","originalFileLocation":"api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Owner only. JSON body { \u0026quot;accessType\u0026quot;: \u0026quot;org_shared\u0026quot;, \u0026quot;organizationId\u0026quot;: \u0026quot;\u0026quot; } switches a private artifact to org_shared and sets organizationId to that id. The id must be the caller\u0026#x27;s current membership. The only explicit row lock is the artifact. The organization foreign-key check takes an implicit KEY SHARE lock on the organization row. The update does not lock the user, the session, or membership rows. It re-checks membership and, for a session, that the session is still present and unexpired, in the conditional UPDATE. That statement is the linearization point. A different current organization at that snapshot is 409 ORGANIZATION_CHANGED and does not write. A membership removal, organization deletion, active-organization change, or session revocation that commits before the statement reads its rows returns 409, 400, or 401 UNAUTHENTICATED with no write. An authorization change that commits after that snapshot can land before the transaction commits and does not cancel the share. A deadlock, serialization failure, or lock timeout retries once and then returns 409 ORGANIZATION_CHANGED with no write. About 16 seconds is the budget for those two attempts, not a deadline for this endpoint. The update matches the id, the creator, and accessType private, so concurrent requests leave one organization-shared row. An artifact that is already org_shared returns 200 and does not change its organization, share token, or share password, for any confirmed organizationId and whether or not the caller has a current organization. This route does not create or remove a public share, and it does not change an organization-shared artifact back to private. Cookie-authenticated writes need Origin or Referer to be WEB_ORIGIN or PUBLIC_BASE_URL.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Factrove\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/factrove/_generated/favicon/apple-touch-icon.png?v=3\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/factrove/_generated/favicon/favicon-32x32.png?v=3\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/factrove/_generated/favicon/favicon-16x16.png?v=3\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/factrove/_generated/favicon/favicon.ico?v=3\">\u003cmeta data-mint-head property=\"og:title\" content=\"Share a private artifact with the confirmed organization - Factrove\">\u003cmeta data-mint-head property=\"og:description\" content=\"Owner only. JSON body { \u0026quot;accessType\u0026quot;: \u0026quot;org_shared\u0026quot;, \u0026quot;organizationId\u0026quot;: \u0026quot;\u0026quot; } switches a private artifact to org_shared and sets organizationId to that id. The id must be the caller\u0026#x27;s current membership. The only explicit row lock is the artifact. The organization foreign-key check takes an implicit KEY SHARE lock on the organization row. The update does not lock the user, the session, or membership rows. It re-checks membership and, for a session, that the session is still present and unexpired, in the conditional UPDATE. That statement is the linearization point. A different current organization at that snapshot is 409 ORGANIZATION_CHANGED and does not write. A membership removal, organization deletion, active-organization change, or session revocation that commits before the statement reads its rows returns 409, 400, or 401 UNAUTHENTICATED with no write. An authorization change that commits after that snapshot can land before the transaction commits and does not cancel the share. A deadlock, serialization failure, or lock timeout retries once and then returns 409 ORGANIZATION_CHANGED with no write. About 16 seconds is the budget for those two attempts, not a deadline for this endpoint. The update matches the id, the creator, and accessType private, so concurrent requests leave one organization-shared row. An artifact that is already org_shared returns 200 and does not change its organization, share token, or share password, for any confirmed organizationId and whether or not the caller has a current organization. This route does not create or remove a public share, and it does not change an organization-shared artifact back to private. Cookie-authenticated writes need Origin or Referer to be WEB_ORIGIN or PUBLIC_BASE_URL.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Factrove\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://factrove.mintlify.app/api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://factrove.mintlify.site/_mintlify/api/og/v2?division=Artifacts\u0026amp;title=Share+a+private+artifact+with+the+confirmed+organization\u0026amp;description=Owner+only.+JSON+body+%60%7B+%22accessType%22%3A+%22org_shared%22%2C+%22organizationId%22%3A+%22%3Ccurrent+organization+id%3E%22+%7D%60+switches+a+private+artifact+to+%60org_shared%60+and+sets+%60orga\u0026amp;theme=ded3e32c59d8f988115330c3\u0026amp;signature=8d7532cc83c74b7dd01faba3b915ff5e5eb2b871bce7f7581ea5bd012cac931b\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Share a private artifact with the confirmed organization - Factrove\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Owner only. JSON body { \u0026quot;accessType\u0026quot;: \u0026quot;org_shared\u0026quot;, \u0026quot;organizationId\u0026quot;: \u0026quot;\u0026quot; } switches a private artifact to org_shared and sets organizationId to that id. The id must be the caller\u0026#x27;s current membership. The only explicit row lock is the artifact. The organization foreign-key check takes an implicit KEY SHARE lock on the organization row. The update does not lock the user, the session, or membership rows. It re-checks membership and, for a session, that the session is still present and unexpired, in the conditional UPDATE. That statement is the linearization point. A different current organization at that snapshot is 409 ORGANIZATION_CHANGED and does not write. A membership removal, organization deletion, active-organization change, or session revocation that commits before the statement reads its rows returns 409, 400, or 401 UNAUTHENTICATED with no write. An authorization change that commits after that snapshot can land before the transaction commits and does not cancel the share. A deadlock, serialization failure, or lock timeout retries once and then returns 409 ORGANIZATION_CHANGED with no write. About 16 seconds is the budget for those two attempts, not a deadline for this endpoint. The update matches the id, the creator, and accessType private, so concurrent requests leave one organization-shared row. An artifact that is already org_shared returns 200 and does not change its organization, share token, or share password, for any confirmed organizationId and whether or not the caller has a current organization. This route does not create or remove a public share, and it does not change an organization-shared artifact back to private. Cookie-authenticated writes need Origin or Referer to be WEB_ORIGIN or PUBLIC_BASE_URL.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://factrove.mintlify.site/_mintlify/api/og/v2?division=Artifacts\u0026amp;title=Share+a+private+artifact+with+the+confirmed+organization\u0026amp;description=Owner+only.+JSON+body+%60%7B+%22accessType%22%3A+%22org_shared%22%2C+%22organizationId%22%3A+%22%3Ccurrent+organization+id%3E%22+%7D%60+switches+a+private+artifact+to+%60org_shared%60+and+sets+%60orga\u0026amp;theme=ded3e32c59d8f988115330c3\u0026amp;signature=8d7532cc83c74b7dd01faba3b915ff5e5eb2b871bce7f7581ea5bd012cac931b\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"https://mintlify.s3.us-west-1.amazonaws.com/factrove/_generated/favicon/browserconfig.xml?v=3\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Factrove\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#5e64d6\">\u003clink data-mint-head rel=\"canonical\" href=\"https://factrove.mintlify.app/api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://factrove.mintlify.app/#organization\",\"name\":\"Factrove\",\"url\":\"https://factrove.mintlify.app\"},{\"@type\":\"WebSite\",\"@id\":\"https://factrove.mintlify.app#website\",\"name\":\"Factrove\",\"url\":\"https://factrove.mintlify.app\",\"publisher\":{\"@id\":\"https://factrove.mintlify.app/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://factrove.mintlify.app/api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization#webpage\",\"url\":\"https://factrove.mintlify.app/api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization\",\"name\":\"Share a private artifact with the confirmed organization\",\"description\":\"Owner only. JSON body { \\\"accessType\\\": \\\"org_shared\\\", \\\"organizationId\\\": \\\"\\\" } switches a private artifact to org_shared and sets organizationId to that id. The id must be the caller's current membership. The only explicit row lock is the artifact. The organization foreign-key check takes an implicit KEY SHARE lock on the organization row. The update does not lock the user, the session, or membership rows. It re-checks membership and, for a session, that the session is still present and unexpired, in the conditional UPDATE. That statement is the linearization point. A different current organization at that snapshot is 409 ORGANIZATION_CHANGED and does not write. A membership removal, organization deletion, active-organization change, or session revocation that commits before the statement reads its rows returns 409, 400, or 401 UNAUTHENTICATED with no write. An authorization change that commits after that snapshot can land before the transaction commits and does not cancel the share. A deadlock, serialization failure, or lock timeout retries once and then returns 409 ORGANIZATION_CHANGED with no write. About 16 seconds is the budget for those two attempts, not a deadline for this endpoint. The update matches the id, the creator, and accessType private, so concurrent requests leave one organization-shared row. An artifact that is already org_shared returns 200 and does not change its organization, share token, or share password, for any confirmed organizationId and whether or not the caller has a current organization. This route does not create or remove a public share, and it does not change an organization-shared artifact back to private. Cookie-authenticated writes need Origin or Referer to be WEB_ORIGIN or PUBLIC_BASE_URL.\",\"dateModified\":\"2026-11-07T10:02:38.509Z\",\"isPartOf\":{\"@id\":\"https://factrove.mintlify.app#website\"},\"breadcrumb\":{\"@id\":\"https://factrove.mintlify.app/api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://factrove.mintlify.app/api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Artifacts\",\"item\":\"https://factrove.mintlify.app/api-reference/artifacts/list-artifacts-for-the-caller\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Share a private artifact with the confirmed organization\",\"item\":\"https://factrove.mintlify.app/api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://factrove.mintlify.app/api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization#apireference\",\"headline\":\"Share a private artifact with the confirmed organization\",\"name\":\"Share a private artifact with the confirmed organization\",\"description\":\"Owner only. JSON body { \\\"accessType\\\": \\\"org_shared\\\", \\\"organizationId\\\": \\\"\\\" } switches a private artifact to org_shared and sets organizationId to that id. The id must be the caller's current membership. The only explicit row lock is the artifact. The organization foreign-key check takes an implicit KEY SHARE lock on the organization row. The update does not lock the user, the session, or membership rows. It re-checks membership and, for a session, that the session is still present and unexpired, in the conditional UPDATE. That statement is the linearization point. A different current organization at that snapshot is 409 ORGANIZATION_CHANGED and does not write. A membership removal, organization deletion, active-organization change, or session revocation that commits before the statement reads its rows returns 409, 400, or 401 UNAUTHENTICATED with no write. An authorization change that commits after that snapshot can land before the transaction commits and does not cancel the share. A deadlock, serialization failure, or lock timeout retries once and then returns 409 ORGANIZATION_CHANGED with no write. About 16 seconds is the budget for those two attempts, not a deadline for this endpoint. The update matches the id, the creator, and accessType private, so concurrent requests leave one organization-shared row. An artifact that is already org_shared returns 200 and does not change its organization, share token, or share password, for any confirmed organizationId and whether or not the caller has a current organization. This route does not create or remove a public share, and it does not change an organization-shared artifact back to private. Cookie-authenticated writes need Origin or Referer to be WEB_ORIGIN or PUBLIC_BASE_URL.\",\"url\":\"https://factrove.mintlify.app/api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization\",\"mainEntityOfPage\":{\"@id\":\"https://factrove.mintlify.app/api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization#webpage\"},\"dateModified\":\"2026-11-07T10:02:38.509Z\",\"publisher\":{\"@id\":\"https://factrove.mintlify.app/#organization\"},\"isPartOf\":{\"@id\":\"https://factrove.mintlify.app#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Factrove\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Factrove","nav":{"global":null,"tabs":[{"tab":"Get started","pages":[{"title":"Get started","href":"/introduction"}]},{"tab":"Guides","pages":[{"title":"Guides","href":"/guides/self-hosting"}]},{"tab":"CLI reference","pages":[{"title":"CLI reference","href":"/cli-reference/overview"}]},{"tab":"API reference","groups":[{"group":"Overview","pages":[{"title":"API overview","href":"/api-reference/overview"}]},{"group":"Health","pages":[{"title":"Check that the API is initialized","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/health","href":"/api-reference/health/check-that-the-api-is-initialized"}]},{"group":"Auth","pages":[{"title":"Return the caller and current organization","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/context","href":"/api-reference/auth/return-the-caller-and-current-organization"},{"title":"Create an account with email and password","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /api/auth/sign-up/email","href":"/api-reference/auth/create-an-account-with-email-and-password"},{"title":"Sign in with email and password","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /api/auth/sign-in/email","href":"/api-reference/auth/sign-in-with-email-and-password"},{"title":"Create an API key","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /api/auth/api-key/create","href":"/api-reference/auth/create-an-api-key"},{"title":"List API keys for the session","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/auth/api-key/list","href":"/api-reference/auth/list-api-keys-for-the-session"},{"title":"Revoke an API key","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /api/auth/api-key/delete","href":"/api-reference/auth/revoke-an-api-key"}]},{"group":"Artifacts","pages":[{"title":"List artifacts for the caller","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/artifacts","href":"/api-reference/artifacts/list-artifacts-for-the-caller"},{"title":"Upload an HTML file","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /api/v1/artifacts","href":"/api-reference/artifacts/upload-an-html-file"},{"title":"Download artifact HTML or converted Markdown","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/artifacts/{id}/content","href":"/api-reference/artifacts/download-artifact-html-or-converted-markdown"},{"title":"Replace an artifact's stored HTML","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json put /api/v1/artifacts/{id}/content","href":"/api-reference/artifacts/replace-an-artifacts-stored-html"},{"title":"Get artifact metadata","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/artifacts/{id}","href":"/api-reference/artifacts/get-artifact-metadata"},{"title":"Delete an artifact","description":"Owner only. Deletes the artifact row and the current HTML object. The creator is the only caller who can delete. Organization role is not consulted, so an organization admin who did not create the artifact cannot delete it. A missing id and a caller who is not the creator, including a member who can read an org_shared artifact, return the same 404 as an unknown id. The object for the revision that was read is removed first. The row is deleted only while that creator, revision, and object key are still current. A replace that commits in between keeps its row, and this request reads that row and tries again. A missing object still allows that row delete. After eight attempts that each lose to a newer replace, the response is `409 CONTENT_CONFLICT`. Retry DELETE. A storage failure keeps the row. The object may already be gone, so retry DELETE. A public link stops working because the row, including its share token, is gone. Older objects left behind by a failed content replace are not swept. Cookie-authenticated writes need an allowed Origin.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json delete /api/v1/artifacts/{id}","href":"/api-reference/artifacts/delete-an-artifact"},{"title":"Share a private artifact with the confirmed organization","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json patch /api/v1/artifacts/{id}","href":"/api-reference/artifacts/share-a-private-artifact-with-the-confirmed-organization"},{"title":"Rename an artifact","description":"Owner only. Changes the library name and leaves the HTML object, content revision, access, organization, and share columns unchanged. The creator is the only caller who can rename. Organization role is not consulted, so an organization admin who did not create the artifact cannot rename it. A missing id and a caller who is not the creator, including a member who can read an org_shared artifact, return the same 404 as an unknown id. Cookie-authenticated writes need an allowed Origin.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json patch /api/v1/artifacts/{id}/name","href":"/api-reference/artifacts/rename-an-artifact"}]},{"group":"Shares","pages":[{"title":"Read the owner share state","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/artifacts/{id}/share","href":"/api-reference/shares/read-the-owner-share-state"},{"title":"Create or update a public share","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /api/v1/artifacts/{id}/share","href":"/api-reference/shares/create-or-update-a-public-share"},{"title":"Revoke the public share","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json delete /api/v1/artifacts/{id}/share","href":"/api-reference/shares/revoke-the-public-share"},{"title":"Remove the password from a shared link","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json delete /api/v1/artifacts/{id}/share/password","href":"/api-reference/shares/remove-the-password-from-a-shared-link"}]},{"group":"Public","pages":[{"title":"Read a public share","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/public/artifacts/{id}/{token}","href":"/api-reference/public/read-a-public-share"},{"title":"Unlock a password-protected share","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /api/v1/public/artifacts/{id}/{token}/unlock","href":"/api-reference/public/unlock-a-password-protected-share"},{"title":"Download public share HTML","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/public/artifacts/{id}/{token}/content","href":"/api-reference/public/download-public-share-html"}]}]}]},"basePath":"","title":"Share a private artifact with the confirmed organization - Factrove","buildId":"dpl_DTau1J5HqS9UTgVSDwGksstFWtPa","deploymentId":"dpl_DTau1J5HqS9UTgVSDwGksstFWtPa","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-5FCzAcfS.js","utils-SLtAG4EZ.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-2DZi8ZMu.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-D7J3nkzE.js","snippetPresets-D0Alv0AH.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-BI4qNJ2c.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-BD3uyr8j.js","shallow-D8iEBr5z.js","getApiPlaygroundDisplay-CgNP4lzR.js","CodeSnippet-CX-QHuMs.js","CodeSnippets-VlXE-ZUf.js","Page-D9ithiIZ.js","getPastedJson-DYNQkZ1M.js","icon-CzacdwOi.js","MethodPill-2JVqoYKi.js","DuplicateIcon-_xVXs-U8.js","createIcon-BRHrweLo.js","DynamicMarkdown-mQG_iQiE.js","SectionHeading-DMpJzv8f.js","axios-vUo_bRtp.js","Markdown-5FGIym-8.js","clsx-D-TRO5q5.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-CdrJecqK.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-CHlcWBLM.js"]}