PageSourceSearch

https://filedgr-docs.netlify.app/assets/js/80485e55.096c9f22.js

js filedgr-docs.netlify.app collected 2026-10-03 11:10:06 UTC 9,718 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkfiledgr_docs||=[]).push([[2695],{93584(e,n,t){t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"getting-started/credits","title":"Credits & Billing","description":"Creating things costs credits. Credits come from a subscription. If you have none, creation fails","source":"@site/docs/getting-started/credits.md","sourceDirName":"getting-started","slug":"/getting-started/credits","permalink":"/docs/getting-started/credits","draft":false,"unlisted":false,"editUrl":"https://github.com/filedgr/documentation/edit/main/docs/getting-started/credits.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docsSidebar","previous":{"title":"Conventions","permalink":"/docs/getting-started/conventions"},"next":{"title":"Vaults","permalink":"/docs/core-concepts/vaults"}}');var i=t(74848),r=t(28453);const a={},o="Credits & Billing",c={},d=[{value:"What things cost",id:"what-things-cost",level:2},{value:"Who pays",id:"who-pays",level:2},{value:"Checking your balance",id:"checking-your-balance",level:2},{value:"Two different 402s",id:"two-different-402s",level:2},{value:"The credit check is not a guarantee",id:"the-credit-check-is-not-a-guarantee",level:2},{value:"Plans and subscriptions",id:"plans-and-subscriptions",level:2},{value:"Payment happens outside the API",id:"payment-happens-outside-the-api",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"credits--billing",children:"Credits & Billing"})}),"\n",(0,i.jsxs)(n.p,{children:["Creating things costs credits. Credits come from a subscription. If you have none, creation fails\nwith a ",(0,i.jsx)(n.a,{href:"conventions#402-carries-extra-fields",children:"402"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"what-things-cost",children:"What things cost"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Operation"}),(0,i.jsx)(n.th,{children:"Credits"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Create a vault"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Create a stream"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Create a data attachment"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Create a signature"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsxs)(n.p,{children:["Setting ",(0,i.jsx)(n.code,{children:"short_url"})," in the ",(0,i.jsx)(n.code,{children:"config"})," of a vault or data attachment costs ",(0,i.jsx)(n.strong,{children:"one extra credit"}),". A\nvault created with a short URL costs 2, not 1. This surcharge is not visible in the request schema\nand is the usual explanation for a balance dropping faster than expected."]})}),"\n",(0,i.jsx)(n.h2,{id:"who-pays",children:"Who pays"}),"\n",(0,i.jsx)(n.p,{children:"Not necessarily the caller."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Vaults"})," are charged to the entity of the API key making the call."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Streams and data attachments"})," are charged to the ",(0,i.jsx)(n.strong,{children:"vault owner"}),", resolved from the vault."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"So if you write into a vault someone else owns and has shared with you, their credits are spent, not\nyours."}),"\n",(0,i.jsx)(n.h2,{id:"checking-your-balance",children:"Checking your balance"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'curl "$FILEDGR_API/balances" \\\n  -H "x-api-key: $FILEDGR_API_KEY" -H "x-api-secret: $FILEDGR_API_SECRET"\n'})}),"\n",(0,i.jsx)(n.p,{children:"Returns the current balance and its timestamps. There is no consumption history or ledger \u2014 track\nyour own spend if you need an audit trail."}),"\n",(0,i.jsxs)(n.p,{children:["On renewal the balance is ",(0,i.jsx)(n.strong,{children:"replaced"}
1)," with the period allowance rather than added to it, so unused\ncredits do not roll over. An annual payment sets twelve times the plan's monthly allowance up front."]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"GET /plans"})," defaults to ",(0,i.jsx)(n.code,{children:"plan_type=CORPORATE"}),". Pass ",(0,i.jsx)(n.code,{children:"?plan_type=PERSONAL"})," explicitly if you are\nlooking for personal plans, or the list will look empty."]})}),"\n",(0,i.jsx)(n.h2,{id:"two-different-402s",children:"Two different 402s"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"has_subscription"})," field distinguishes them, and they need different handling:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{ "error": "InsufficientCreditsError", "message": "...",\n  "required": 1.0, "balance": 0.0, "has_subscription": false }\n'})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"has_subscription: false"})," \u2014 no active subscription. Subscribe."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"has_subscription: true"})," \u2014 subscribed but out of credits. Wait for renewal or top up."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"the-credit-check-is-not-a-guarantee",children:"The credit check is not a guarantee"}),"\n",(0,i.jsxs)(n.admonition,{type:"warning",children:[(0,i.jsxs)(n.p,{children:["The pre-flight check ",(0,i.jsx)(n.strong,{children:"fails open"}),". If the billing service is unreachable, or the vault behind a\nstream cannot be resolved, creation is allowed to proceed and the shortfall is caught later \u2014\nthe resource ends up in an ",(0,i.jsx)(n.code,{children:"ERROR"})," state instead of being refused up front."]}),(0,i.jsxs)(n.p,{children:["The absence of a 402 therefore does not guarantee the operation will complete. Watch for the\n",(0,i.jsx)(n.code,{children:"*.failed"})," and ",(0,i.jsx)(n.code,{children:"*.error"})," ",(0,i.jsx)(n.a,{href:"../integration/webhooks",children:"webhook events"}),", and check\n",(0,i.jsx)(n.a,{href:"../integration/retries",children:"entity status"})," when something stalls."]})]}),"\n",(0,i.jsx)(n.p,{children:"The actual deduction happens asynchronously in a locked transaction after the pre-flight, so two\nconcurrent creates can both pass the check and one can still fail."}),"\n",(0,i.jsx)(n.h2,{id:"plans-and-subscriptions",children:"Plans and subscriptions"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"GET  /plans                       list available plans\nGET  /plans/{plan_id}             plan detail\nPOST /subscriptions               subscribe to a plan\nGET  /subscriptions               your subscriptions\nGET  /subscriptions/{id}          subscription detail\n"})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"One subscription per entity."})," Attempting a second returns ",(0,i.jsx)(n.strong,{children:"400"})," (not 409, despite the\nconflict semantics)."]}),"\n",(0,i.jsxs)(n.p,{children:["A subscription moves through ",(0,i.jsx)(n.code,{children:"FILEDGR_RECEIVED"})," \u2192 ",(0,i.jsx)(n.code,{children:"PAYMENT_PROCESSOR_RECEIVED"})," \u2192\n",(0,i.jsx)(n.code,{children:"PAYMENT_PROCESSOR_COMPLETED"})," \u2192 ",(0,i.jsx)(n.code,{children:"FILEDGR_PROCESSOR_COMPLETED"}),". ",(0,i.jsx)(n.strong,{children:"Credits only arrive at the final\nstate."})]}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsxs)(n.p,{children:["The final state serialises as ",(0,i.jsx)(n.code,{children:"FILEDGR_PROCESSOR_COMPLETED"}),". Some internal code refers to it by the\nshorter name ",(0,i.jsx)(n.code,{children:"FILEDGR_COMPLETED"})," \u2014 match on the value above, or your poll loop will never terminate."]})}),"\n",(0,i.jsx)(n.h3,{id:"payment-happens-outside-the-api",children:"Payment happens outside the API"}),"\n",(0,i.jsxs)(n.p,{children:["Subscription responses carry a ",(0,i.jsx)(n.code,{children:"links"})," object with ",(0,i.jsx)(n.code,{children:"subscription_link"}),", and ",(0,i.jsx)(n.code,{children:"payment_link"})," when\nthere is an outstanding payment. Payment is completed through those links in a browser \u2014 there is no\nAPI call that settles it."]}),"\n",(0,i.jsx)(n.admonition,{type:"danger",children:(0,i.jsxs)(n.p,{children:["Subscription links require an ",(0,i.jsx)(n.strong,{children:"email credential"})," on the account. An API key whose holder has no\nemail credential gets a ",(0,i.jsx)(n.strong,{children:"404"})," explaining that no links can be issued, which makes subscribing\nimpossible from a pure machine integration. Have a person subscribe through the web app first, then\nuse the API key against the subscribed entity."]})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453(e,n,t){t.d(n,{R:()=>a,x:()=>o});var s=t(96540);const i={},r=s.createContext(i);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.