apifacts 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. apifacts-0.1.0/.gitignore +35 -0
  2. apifacts-0.1.0/LICENSE +21 -0
  3. apifacts-0.1.0/LICENSE-DATA +9 -0
  4. apifacts-0.1.0/PKG-INFO +94 -0
  5. apifacts-0.1.0/README.en.md +68 -0
  6. apifacts-0.1.0/apifacts/__init__.py +3 -0
  7. apifacts-0.1.0/apifacts/api/__init__.py +5 -0
  8. apifacts-0.1.0/apifacts/api/app.py +487 -0
  9. apifacts-0.1.0/apifacts/api/facts_index.py +286 -0
  10. apifacts-0.1.0/apifacts/api/health.py +67 -0
  11. apifacts-0.1.0/apifacts/api/match.py +194 -0
  12. apifacts-0.1.0/apifacts/api/models.py +149 -0
  13. apifacts-0.1.0/apifacts/api/normalize.py +249 -0
  14. apifacts-0.1.0/apifacts/api/ratelimit.py +67 -0
  15. apifacts-0.1.0/apifacts/api/schema.sql +42 -0
  16. apifacts-0.1.0/apifacts/api/seed_hosts.py +323 -0
  17. apifacts-0.1.0/apifacts/api/store.py +110 -0
  18. apifacts-0.1.0/apifacts/bot/__init__.py +1 -0
  19. apifacts-0.1.0/apifacts/bot/cli.py +73 -0
  20. apifacts-0.1.0/apifacts/bot/collect.py +146 -0
  21. apifacts-0.1.0/apifacts/bot/pr.py +327 -0
  22. apifacts-0.1.0/apifacts/bot/token.py +96 -0
  23. apifacts-0.1.0/apifacts/cli.py +96 -0
  24. apifacts-0.1.0/apifacts/cli_check.py +94 -0
  25. apifacts-0.1.0/apifacts/client/__init__.py +6 -0
  26. apifacts-0.1.0/apifacts/client/offline.py +142 -0
  27. apifacts-0.1.0/apifacts/client/render.py +117 -0
  28. apifacts-0.1.0/apifacts/client/request.py +251 -0
  29. apifacts-0.1.0/apifacts/client/settings.py +26 -0
  30. apifacts-0.1.0/apifacts/client/snapshot/README.md +6 -0
  31. apifacts-0.1.0/apifacts/client/transport.py +235 -0
  32. apifacts-0.1.0/apifacts/fixes/__init__.py +1 -0
  33. apifacts-0.1.0/apifacts/fixes/templates.py +84 -0
  34. apifacts-0.1.0/apifacts/pages/__init__.py +5 -0
  35. apifacts-0.1.0/apifacts/pages/build.py +215 -0
  36. apifacts-0.1.0/apifacts/pages/cli.py +74 -0
  37. apifacts-0.1.0/apifacts/pages/errors_index.py +42 -0
  38. apifacts-0.1.0/apifacts/pages/templates.py +364 -0
  39. apifacts-0.1.0/apifacts/probe/__init__.py +12 -0
  40. apifacts-0.1.0/apifacts/probe/assertions.py +170 -0
  41. apifacts-0.1.0/apifacts/probe/budget.py +131 -0
  42. apifacts-0.1.0/apifacts/probe/cli.py +145 -0
  43. apifacts-0.1.0/apifacts/probe/evidence.py +280 -0
  44. apifacts-0.1.0/apifacts/probe/google_sa.py +148 -0
  45. apifacts-0.1.0/apifacts/probe/http.py +281 -0
  46. apifacts-0.1.0/apifacts/probe/keys.py +43 -0
  47. apifacts-0.1.0/apifacts/probe/ledger.py +90 -0
  48. apifacts-0.1.0/apifacts/probe/loader.py +93 -0
  49. apifacts-0.1.0/apifacts/probe/oauth_refresh.py +127 -0
  50. apifacts-0.1.0/apifacts/probe/redact.py +123 -0
  51. apifacts-0.1.0/apifacts/probe/results.py +147 -0
  52. apifacts-0.1.0/apifacts/probe/runner.py +700 -0
  53. apifacts-0.1.0/apifacts/probe/templating.py +138 -0
  54. apifacts-0.1.0/apifacts/quorum/__init__.py +2 -0
  55. apifacts-0.1.0/apifacts/quorum/cli.py +87 -0
  56. apifacts-0.1.0/apifacts/quorum/draft.py +163 -0
  57. apifacts-0.1.0/apifacts/quorum/group.py +123 -0
  58. apifacts-0.1.0/apifacts/quorum/rules.py +82 -0
  59. apifacts-0.1.0/apifacts/quorum/run.py +132 -0
  60. apifacts-0.1.0/apifacts/schema/__init__.py +39 -0
  61. apifacts-0.1.0/apifacts/schema/error_paths.py +44 -0
  62. apifacts-0.1.0/apifacts/schema/models.py +702 -0
  63. apifacts-0.1.0/apifacts/schema/registry.py +238 -0
  64. apifacts-0.1.0/apifacts/schema/substance.py +24 -0
  65. apifacts-0.1.0/apifacts/schema/validate.py +433 -0
  66. apifacts-0.1.0/apifacts/schema/yamlio.py +70 -0
  67. apifacts-0.1.0/facts/github/anonymous-cache-ignores-api-version.yaml +29 -0
  68. apifacts-0.1.0/facts/github/anonymous-core-rate-limit.yaml +27 -0
  69. apifacts-0.1.0/facts/github/anonymous-repo-has-no-permissions.yaml +26 -0
  70. apifacts-0.1.0/facts/github/anonymous-search-rate-limit.yaml +27 -0
  71. apifacts-0.1.0/facts/github/api-version-2026-drops-has-downloads.yaml +27 -0
  72. apifacts-0.1.0/facts/github/default-api-version-end-of-support.yaml +22 -0
  73. apifacts-0.1.0/facts/github/error-status-is-a-string.yaml +28 -0
  74. apifacts-0.1.0/facts/github/graphql-anonymous-limit-zero.yaml +27 -0
  75. apifacts-0.1.0/facts/github/missing-repo-404.yaml +30 -0
  76. apifacts-0.1.0/facts/github/pagination-in-link-header.yaml +27 -0
  77. apifacts-0.1.0/facts/github/per-page-silently-capped-at-100.yaml +27 -0
  78. apifacts-0.1.0/facts/github/private-repo-404-not-403.yaml +26 -0
  79. apifacts-0.1.0/facts/github/rate-object-closing-down.yaml +22 -0
  80. apifacts-0.1.0/facts/github/renamed-repo-301.yaml +31 -0
  81. apifacts-0.1.0/facts/github/repository-object-fingerprint.yaml +26 -0
  82. apifacts-0.1.0/facts/github/search-first-1000-results.yaml +31 -0
  83. apifacts-0.1.0/facts/github/search-query-longer-than-256.yaml +31 -0
  84. apifacts-0.1.0/facts/github/secondary-rate-limit-429.yaml +25 -0
  85. apifacts-0.1.0/facts/github/secondary-rate-limit.yaml +25 -0
  86. apifacts-0.1.0/facts/github/trailing-slash-404.yaml +31 -0
  87. apifacts-0.1.0/facts/github/unsupported-api-version-400.yaml +31 -0
  88. apifacts-0.1.0/facts/github/unsupported-method-404.yaml +24 -0
  89. apifacts-0.1.0/facts/github/user-agent-required.yaml +24 -0
  90. apifacts-0.1.0/facts/google-calendar/calendar-get-rejects-api-keys.yaml +31 -0
  91. apifacts-0.1.0/facts/google-calendar/calendar-not-found-404.yaml +30 -0
  92. apifacts-0.1.0/facts/google-calendar/events-page-default-250.yaml +22 -0
  93. apifacts-0.1.0/facts/google-calendar/invalid-page-token-400.yaml +30 -0
  94. apifacts-0.1.0/facts/google-calendar/max-results-above-2500-accepted.yaml +29 -0
  95. apifacts-0.1.0/facts/google-calendar/max-results-zero-refused.yaml +30 -0
  96. apifacts-0.1.0/facts/google-calendar/missing-api-key-403.yaml +30 -0
  97. apifacts-0.1.0/facts/google-calendar/order-by-start-time-needs-single-events.yaml +30 -0
  98. apifacts-0.1.0/facts/google-calendar/public-free-busy-calendar-via-api-key.yaml +28 -0
  99. apifacts-0.1.0/facts/google-calendar/rate-limit-403-or-429.yaml +24 -0
  100. apifacts-0.1.0/facts/google-calendar/sync-token-with-time-min-400.yaml +30 -0
  101. apifacts-0.1.0/facts/google-calendar/time-min-filters-on-end-time.yaml +22 -0
  102. apifacts-0.1.0/facts/google-calendar/time-min-without-offset-bad-request.yaml +31 -0
  103. apifacts-0.1.0/facts/google-calendar/unknown-sync-token-410.yaml +30 -0
  104. apifacts-0.1.0/facts/google-firestore/array-and-map-values-are-wrapped.yaml +28 -0
  105. apifacts-0.1.0/facts/google-firestore/document-envelope-keys.yaml +28 -0
  106. apifacts-0.1.0/facts/google-firestore/document-not-found-404.yaml +31 -0
  107. apifacts-0.1.0/facts/google-firestore/document-size-limit-1mib.yaml +22 -0
  108. apifacts-0.1.0/facts/google-firestore/empty-collection-returns-empty-object.yaml +28 -0
  109. apifacts-0.1.0/facts/google-firestore/free-quota-resets-midnight-pacific.yaml +22 -0
  110. apifacts-0.1.0/facts/google-firestore/integer-value-is-a-string.yaml +29 -0
  111. apifacts-0.1.0/facts/google-firestore/invalid-field-path-400.yaml +31 -0
  112. apifacts-0.1.0/facts/google-firestore/invalid-page-token-400.yaml +31 -0
  113. apifacts-0.1.0/facts/google-firestore/negative-page-size-400.yaml +31 -0
  114. apifacts-0.1.0/facts/google-firestore/null-value-is-json-null.yaml +28 -0
  115. apifacts-0.1.0/facts/google-firestore/order-by-unknown-field-accepted.yaml +28 -0
  116. apifacts-0.1.0/facts/google-firestore/server-access-bypasses-security-rules.yaml +22 -0
  117. apifacts-0.1.0/facts/google-firestore/subcollection-of-missing-document-is-empty.yaml +28 -0
  118. apifacts-0.1.0/facts/google-firestore/timestamp-value-rfc3339-utc.yaml +28 -0
  119. apifacts-0.1.0/facts/google-firestore/unauthenticated-read-under-test-mode.yaml +31 -0
  120. apifacts-0.1.0/facts/google-firestore/unknown-database-404.yaml +31 -0
  121. apifacts-0.1.0/facts/google-firestore/unknown-project-403.yaml +31 -0
  122. apifacts-0.1.0/facts/google-gemini/daily-quota-resets-midnight-pacific.yaml +22 -0
  123. apifacts-0.1.0/facts/google-gemini/errors-use-google-rpc-envelope.yaml +28 -0
  124. apifacts-0.1.0/facts/google-gemini/gemini-1-5-models-retired.yaml +31 -0
  125. apifacts-0.1.0/facts/google-gemini/gemini-2-0-flash-served-past-shutdown-date.yaml +29 -0
  126. apifacts-0.1.0/facts/google-gemini/invalid-api-key-400.yaml +31 -0
  127. apifacts-0.1.0/facts/google-gemini/invalid-page-token-400.yaml +31 -0
  128. apifacts-0.1.0/facts/google-gemini/latest-aliases-v1beta-only.yaml +31 -0
  129. apifacts-0.1.0/facts/google-gemini/leaked-key-403.yaml +27 -0
  130. apifacts-0.1.0/facts/google-gemini/missing-api-key-403.yaml +31 -0
  131. apifacts-0.1.0/facts/google-gemini/model-not-found-404.yaml +31 -0
  132. apifacts-0.1.0/facts/google-gemini/model-object-fingerprint.yaml +28 -0
  133. apifacts-0.1.0/facts/google-gemini/models-list-default-page-50.yaml +28 -0
  134. apifacts-0.1.0/facts/google-gemini/page-size-negative-400.yaml +31 -0
  135. apifacts-0.1.0/facts/google-gemini/page-size-zero-means-default.yaml +28 -0
  136. apifacts-0.1.0/facts/google-gemini/rate-limits-per-project.yaml +22 -0
  137. apifacts-0.1.0/facts/google-gemini/resource-exhausted-429.yaml +25 -0
  138. apifacts-0.1.0/facts/google-gemini/unknown-query-parameter-400.yaml +31 -0
  139. apifacts-0.1.0/facts/google-sheets/batch-get-fails-whole.yaml +31 -0
  140. apifacts-0.1.0/facts/google-sheets/columns-major-inner-empty-cells.yaml +28 -0
  141. apifacts-0.1.0/facts/google-sheets/date-time-formatted-string.yaml +28 -0
  142. apifacts-0.1.0/facts/google-sheets/default-sheet-name-follows-locale.yaml +31 -0
  143. apifacts-0.1.0/facts/google-sheets/empty-range-omits-values.yaml +28 -0
  144. apifacts-0.1.0/facts/google-sheets/formatted-values-follow-locale.yaml +28 -0
  145. apifacts-0.1.0/facts/google-sheets/formulas-in-locale-syntax.yaml +28 -0
  146. apifacts-0.1.0/facts/google-sheets/invalid-api-key-400.yaml +31 -0
  147. apifacts-0.1.0/facts/google-sheets/invalid-fields-mask-generic-400.yaml +31 -0
  148. apifacts-0.1.0/facts/google-sheets/invalid-value-render-option-400.yaml +31 -0
  149. apifacts-0.1.0/facts/google-sheets/missing-api-key-403.yaml +31 -0
  150. apifacts-0.1.0/facts/google-sheets/new-sheet-grid-1000x26.yaml +28 -0
  151. apifacts-0.1.0/facts/google-sheets/quota-per-project-and-user.yaml +24 -0
  152. apifacts-0.1.0/facts/google-sheets/range-clipped-to-grid.yaml +28 -0
  153. apifacts-0.1.0/facts/google-sheets/request-timeout-180s.yaml +22 -0
  154. apifacts-0.1.0/facts/google-sheets/spreadsheet-not-found-404.yaml +31 -0
  155. apifacts-0.1.0/facts/google-sheets/unformatted-dates-are-serial-numbers.yaml +28 -0
  156. apifacts-0.1.0/facts/google-sheets/unknown-sheet-unable-to-parse.yaml +31 -0
  157. apifacts-0.1.0/facts/google-sheets/value-rows-not-padded.yaml +28 -0
  158. apifacts-0.1.0/facts/google-sheets/whole-column-range-expanded.yaml +28 -0
  159. apifacts-0.1.0/facts/pypi/downloads-always-minus-one.yaml +27 -0
  160. apifacts-0.1.0/facts/pypi/json-api-accepts-unnormalized-name.yaml +26 -0
  161. apifacts-0.1.0/facts/pypi/json-api-cdn-cache.yaml +27 -0
  162. apifacts-0.1.0/facts/pypi/json-trailing-slash-301.yaml +28 -0
  163. apifacts-0.1.0/facts/pypi/no-edge-rate-limit.yaml +22 -0
  164. apifacts-0.1.0/facts/pypi/project-json-fingerprint.yaml +26 -0
  165. apifacts-0.1.0/facts/pypi/project-not-found-404.yaml +30 -0
  166. apifacts-0.1.0/facts/pypi/release-json-has-no-releases-key.yaml +27 -0
  167. apifacts-0.1.0/facts/pypi/release-metadata-from-first-upload.yaml +22 -0
  168. apifacts-0.1.0/facts/pypi/release-not-found-404.yaml +30 -0
  169. apifacts-0.1.0/facts/pypi/releases-key-deprecated.yaml +22 -0
  170. apifacts-0.1.0/facts/pypi/simple-api-html-unless-accept-json.yaml +27 -0
  171. apifacts-0.1.0/facts/pypi/simple-not-found-404.yaml +30 -0
  172. apifacts-0.1.0/facts/pypi/simple-unnormalized-name-301.yaml +29 -0
  173. apifacts-0.1.0/facts/pypi/simple-without-trailing-slash-301.yaml +28 -0
  174. apifacts-0.1.0/facts/pypi/xml-rpc-planned-deprecation.yaml +22 -0
  175. apifacts-0.1.0/facts/salesforce/developer-edition-15000-daily-requests.yaml +28 -0
  176. apifacts-0.1.0/facts/salesforce/empty-query-result-shape.yaml +28 -0
  177. apifacts-0.1.0/facts/salesforce/errors-are-a-json-array.yaml +28 -0
  178. apifacts-0.1.0/facts/salesforce/missing-session-401.yaml +31 -0
  179. apifacts-0.1.0/facts/salesforce/non-id-path-read-as-external-id.yaml +31 -0
  180. apifacts-0.1.0/facts/salesforce/record-not-found-404.yaml +31 -0
  181. apifacts-0.1.0/facts/salesforce/rest-on-login-host-url-not-reset.yaml +31 -0
  182. apifacts-0.1.0/facts/salesforce/retired-api-version-410.yaml +30 -0
  183. apifacts-0.1.0/facts/salesforce/sforce-limit-info-header.yaml +28 -0
  184. apifacts-0.1.0/facts/salesforce/soap-login-needs-use-any-api-auth.yaml +24 -0
  185. apifacts-0.1.0/facts/salesforce/soap-login-rate-3600-per-hour.yaml +22 -0
  186. apifacts-0.1.0/facts/salesforce/soap-login-retiring-summer-27.yaml +22 -0
  187. apifacts-0.1.0/facts/salesforce/soql-fields-all-needs-limit.yaml +31 -0
  188. apifacts-0.1.0/facts/salesforce/soql-malformed-query-400.yaml +31 -0
  189. apifacts-0.1.0/facts/salesforce/soql-unknown-field-invalid-field.yaml +31 -0
  190. apifacts-0.1.0/facts/salesforce/soql-unknown-object-invalid-type.yaml +31 -0
  191. apifacts-0.1.0/facts/salesforce/unknown-sobject-describe-404.yaml +31 -0
  192. apifacts-0.1.0/facts/salesforce/version-list-needs-no-session.yaml +28 -0
  193. apifacts-0.1.0/facts/solana/get-block-commitment-processed.yaml +31 -0
  194. apifacts-0.1.0/facts/solana/get-confirmed-block-removed.yaml +32 -0
  195. apifacts-0.1.0/facts/solana/get-confirmed-transaction-removed.yaml +32 -0
  196. apifacts-0.1.0/facts/solana/get-program-accounts-blocked-403.yaml +31 -0
  197. apifacts-0.1.0/facts/solana/get-recent-blockhash-removed.yaml +32 -0
  198. apifacts-0.1.0/facts/solana/invalid-pubkey-wrong-size.yaml +31 -0
  199. apifacts-0.1.0/facts/solana/jsonrpc-errors-use-http-200.yaml +28 -0
  200. apifacts-0.1.0/facts/solana/multiple-accounts-max-100.yaml +31 -0
  201. apifacts-0.1.0/facts/solana/per-method-rate-limit-headers.yaml +26 -0
  202. apifacts-0.1.0/facts/solana/public-endpoint-403-blocked.yaml +24 -0
  203. apifacts-0.1.0/facts/solana/public-endpoint-not-for-production.yaml +22 -0
  204. apifacts-0.1.0/facts/solana/public-mainnet-rate-limits.yaml +24 -0
  205. apifacts-0.1.0/facts/solana/rent-exemption-minimum-zero-bytes.yaml +26 -0
  206. apifacts-0.1.0/facts/solana/signatures-for-address-limit-1000.yaml +31 -0
  207. apifacts-0.1.0/facts/stripe/amount-too-small.yaml +31 -0
  208. apifacts-0.1.0/facts/stripe/card-declined-generic.yaml +31 -0
  209. apifacts-0.1.0/facts/stripe/card-expired.yaml +31 -0
  210. apifacts-0.1.0/facts/stripe/card-incorrect-cvc.yaml +31 -0
  211. apifacts-0.1.0/facts/stripe/card-insufficient-funds.yaml +31 -0
  212. apifacts-0.1.0/facts/stripe/card-lost-generic-message.yaml +31 -0
  213. apifacts-0.1.0/facts/stripe/customer-not-found.yaml +31 -0
  214. apifacts-0.1.0/facts/stripe/deleted-customer-returns-200.yaml +28 -0
  215. apifacts-0.1.0/facts/stripe/execution-errors-are-replayed.yaml +31 -0
  216. apifacts-0.1.0/facts/stripe/expand-not-expandable.yaml +30 -0
  217. apifacts-0.1.0/facts/stripe/idempotency-key-other-endpoint.yaml +31 -0
  218. apifacts-0.1.0/facts/stripe/idempotency-key-reuse-different-params.yaml +31 -0
  219. apifacts-0.1.0/facts/stripe/idempotency-key-too-long.yaml +31 -0
  220. apifacts-0.1.0/facts/stripe/idempotency-keys-pruned-after-24h.yaml +22 -0
  221. apifacts-0.1.0/facts/stripe/idempotent-replay-header.yaml +28 -0
  222. apifacts-0.1.0/facts/stripe/invalid-api-version-400.yaml +30 -0
  223. apifacts-0.1.0/facts/stripe/limit-not-an-integer.yaml +31 -0
  224. apifacts-0.1.0/facts/stripe/limit-zero-returns-one.yaml +28 -0
  225. apifacts-0.1.0/facts/stripe/missing-api-key-401.yaml +30 -0
  226. apifacts-0.1.0/facts/stripe/parameter-unknown.yaml +31 -0
  227. apifacts-0.1.0/facts/stripe/payment-method-types-removed.yaml +30 -0
  228. apifacts-0.1.0/facts/stripe/rate-limited-reason-header.yaml +24 -0
  229. apifacts-0.1.0/facts/stripe/sandbox-rate-limit-lower.yaml +22 -0
  230. apifacts-0.1.0/facts/stripe/server-assigned-idempotency-key.yaml +28 -0
  231. apifacts-0.1.0/facts/stripe/starting-after-missing-object.yaml +31 -0
  232. apifacts-0.1.0/facts/stripe/validation-errors-are-not-replayed.yaml +31 -0
  233. apifacts-0.1.0/facts/telegram/chat-id-empty-400.yaml +30 -0
  234. apifacts-0.1.0/facts/telegram/chat-not-found-400.yaml +30 -0
  235. apifacts-0.1.0/facts/telegram/error-envelope-ok-false.yaml +29 -0
  236. apifacts-0.1.0/facts/telegram/flood-control-429-retry-after.yaml +24 -0
  237. apifacts-0.1.0/facts/telegram/get-updates-blocked-by-webhook.yaml +22 -0
  238. apifacts-0.1.0/facts/telegram/get-updates-limit-not-validated.yaml +29 -0
  239. apifacts-0.1.0/facts/telegram/group-migrated-to-supergroup.yaml +22 -0
  240. apifacts-0.1.0/facts/telegram/invalid-file-id-400.yaml +30 -0
  241. apifacts-0.1.0/facts/telegram/invalid-token-401.yaml +30 -0
  242. apifacts-0.1.0/facts/telegram/malformed-token-404.yaml +30 -0
  243. apifacts-0.1.0/facts/telegram/message-rate-limits.yaml +24 -0
  244. apifacts-0.1.0/facts/telegram/method-names-case-insensitive.yaml +29 -0
  245. apifacts-0.1.0/facts/telegram/no-webhook-url-empty-string.yaml +28 -0
  246. apifacts-0.1.0/facts/telegram/unknown-method-404.yaml +30 -0
  247. apifacts-0.1.0/facts/telegram/updates-kept-24-hours.yaml +22 -0
  248. apifacts-0.1.0/facts/telegram/user-not-found-400.yaml +30 -0
  249. apifacts-0.1.0/pyproject.toml +70 -0
  250. apifacts-0.1.0/schema/fact.schema.json +182 -0
  251. apifacts-0.1.0/schema/fix.schema.json +244 -0
  252. apifacts-0.1.0/schema/observation.schema.json +25 -0
  253. apifacts-0.1.0/schema/probe.schema.json +181 -0
  254. apifacts-0.1.0/schema/service.schema.json +215 -0
  255. apifacts-0.1.0/services/github.yaml +44 -0
  256. apifacts-0.1.0/services/google-calendar.yaml +34 -0
  257. apifacts-0.1.0/services/google-firestore.yaml +39 -0
  258. apifacts-0.1.0/services/google-gemini.yaml +35 -0
  259. apifacts-0.1.0/services/google-sheets.yaml +33 -0
  260. apifacts-0.1.0/services/pypi.yaml +34 -0
  261. apifacts-0.1.0/services/salesforce.yaml +38 -0
  262. apifacts-0.1.0/services/solana.yaml +44 -0
  263. apifacts-0.1.0/services/stripe.yaml +41 -0
  264. apifacts-0.1.0/services/telegram.yaml +39 -0
@@ -0,0 +1,35 @@
1
+ # secrets never
2
+ .env
3
+ .env.*
4
+ *.key
5
+ *.pem
6
+ .private_keys/
7
+
8
+ # python
9
+ __pycache__/
10
+ *.pyc
11
+ .venv/
12
+ .pytest_cache/
13
+ .mypy_cache/
14
+ .ruff_cache/
15
+ dist/
16
+ build/
17
+ *.egg-info/
18
+
19
+ # node
20
+ node_modules/
21
+ coverage/
22
+
23
+ # probe runner state (results.jsonl, probe-state.sqlite): transient, never in git
24
+ var/
25
+
26
+ # local scratch
27
+ .DS_Store
28
+ tmp/
29
+
30
+ # check() API state (never in git)
31
+ observations.sqlite
32
+ observations.sqlite-*
33
+
34
+ # kill switch (spec 04): a host-local file, never committed
35
+ ops/KILL
apifacts-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Edouard Baillot
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,9 @@
1
+ Data license
2
+
3
+ Everything under `facts/` (the registry of verified facts, in YAML) and the
4
+ generated fact pages is licensed under Creative Commons Attribution 4.0
5
+ International (CC BY 4.0): https://creativecommons.org/licenses/by/4.0/
6
+
7
+ Attribution: "apifacts registry (CC BY 4.0)" with a link to the fact's
8
+ page or to the repository. Code is licensed separately under the MIT License
9
+ (see LICENSE). Decision 2026-10-17, docs/decisions.md.
@@ -0,0 +1,94 @@
1
+ Metadata-Version: 2.5
2
+ Name: apifacts
3
+ Version: 0.1.0
4
+ Summary: Open registry of verified facts about machine interfaces (APIs, SDKs, CLIs) for AI agents.
5
+ Project-URL: Homepage, https://apifacts.dev
6
+ Project-URL: Repository, https://github.com/Illouminus/apifacts
7
+ Project-URL: Issues, https://github.com/Illouminus/apifacts/issues
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ License-File: LICENSE-DATA
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Topic :: Software Development :: Libraries
15
+ Requires-Python: >=3.12
16
+ Requires-Dist: cryptography>=50.0.2
17
+ Requires-Dist: fastapi>=0.150.0
18
+ Requires-Dist: httpx>=0.28.1
19
+ Requires-Dist: jsonschema>=4.26.0
20
+ Requires-Dist: pydantic>=2.14.1
21
+ Requires-Dist: pyyaml>=6.0.3
22
+ Requires-Dist: ruamel-yaml>=0.19.1
23
+ Requires-Dist: typer>=0.27.3
24
+ Requires-Dist: uvicorn>=0.54.0
25
+ Description-Content-Type: text/markdown
26
+
27
+ # apifacts
28
+
29
+ **A verified changelog of reality for AI agents.** An open registry of typed, dated facts about what
30
+ third-party machine interfaces (HTTP APIs, SDK packages, CLIs) actually do today, as opposed to what
31
+ their docs say.
32
+
33
+ ## Why
34
+
35
+ Interfaces change, docs lag, and nobody tells the agent. Every session pays tokens to rediscover the
36
+ same traps: a `200` with an empty array instead of a `429`, a rate limit reported as `status: 0` in the
37
+ body, an SDK release that silently dropped a field. Documentation tools answer "give me the right docs";
38
+ apifacts answers "the docs are wrong about this endpoint right now, here is the verified difference".
39
+
40
+ ## Install
41
+
42
+ ```bash
43
+ pip install apifacts-pytest # pytest plugin: a test failing on an HTTP error prints the known facts
44
+ uvx apifacts check https://api.stripe.com/v1/charges -X GET --status 401 # CLI (and library)
45
+ ```
46
+
47
+ Both packages are on PyPI, carry the same version and ship together from one tag
48
+ ([release](ops/README.md#release-to-pypi)). The plugin sends nothing until a test fails.
49
+
50
+ ## How a fact is verified
51
+
52
+ - One fact per YAML file in `facts/<service>/`, with a kind (`error_meaning`, `rate_limit`,
53
+ `breaking_change`, ...), the exact error signal, a one-sentence claim, dimensions (`env`, `plan`,
54
+ `region`, `account_state`) and evidence.
55
+ - Truth comes only from **deterministic probes**: declarative HTTP steps and assertions that our runner
56
+ executes on a schedule. No language model is called anywhere in the verification path.
57
+ - Fixes are **data, not advice**: members of a closed vocabulary with typed parameters (no free text, no
58
+ shell, no foreign URLs), rendered to one English sentence by us.
59
+ - A probe in another environment never refutes a fact; it adds a dimension.
60
+
61
+ ## Calling `check()`
62
+
63
+ One endpoint answers and learns at the same time: the request is the contribution. Send the target and,
64
+ optionally, the error you got; receive matching facts with typed fixes and what the probes observe. If
65
+ the target matches a registered template, a normalized observation is stored (no bodies, headers, query
66
+ strings or raw IPs).
67
+
68
+ ```bash
69
+ curl -s https://apifacts.dev/v0/check \
70
+ -H 'Content-Type: application/json' \
71
+ -d '{"target": {"method": "POST", "url": "https://api.stripe.com/v1/payment_intents"},
72
+ "error": {"status": 400, "body_excerpt": "Keys for idempotent requests can only be used with the same parameters they were first used with."}}'
73
+ ```
74
+
75
+ The response is never empty: `facts`, `observed`, and an `unknown.reason` when nothing matches.
76
+
77
+ ## Status
78
+
79
+ The API is live at https://apifacts.dev (`/v0/check`, `/v0/services`, `/openapi.json`, `/healthz`;
80
+ `facts.baillot.dev` is a legacy alias). The registry covers the services and facts listed in
81
+ [`pages/index.md`](pages/index.md), each fact page showing how it was established. Design contracts
82
+ live in [`docs/specs/`](docs/specs/README.md).
83
+
84
+ Running your own copy: the API reads `facts/` and `services/` once, at startup, so after a `git pull`
85
+ restart it; [`ops/deploy.sh`](ops/README.md#deploy) checks out, syncs and restarts in one step.
86
+
87
+ ## Contributing
88
+
89
+ Calling `check()` is contributing. Pull requests are for humans and API producers: see
90
+ [CONTRIBUTING.md](CONTRIBUTING.md). Producer signatures are always free.
91
+
92
+ ## License
93
+
94
+ Code: [MIT](LICENSE). Data (`facts/` and the generated fact pages): [CC BY 4.0](LICENSE-DATA).
@@ -0,0 +1,68 @@
1
+ # apifacts
2
+
3
+ **A verified changelog of reality for AI agents.** An open registry of typed, dated facts about what
4
+ third-party machine interfaces (HTTP APIs, SDK packages, CLIs) actually do today, as opposed to what
5
+ their docs say.
6
+
7
+ ## Why
8
+
9
+ Interfaces change, docs lag, and nobody tells the agent. Every session pays tokens to rediscover the
10
+ same traps: a `200` with an empty array instead of a `429`, a rate limit reported as `status: 0` in the
11
+ body, an SDK release that silently dropped a field. Documentation tools answer "give me the right docs";
12
+ apifacts answers "the docs are wrong about this endpoint right now, here is the verified difference".
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ pip install apifacts-pytest # pytest plugin: a test failing on an HTTP error prints the known facts
18
+ uvx apifacts check https://api.stripe.com/v1/charges -X GET --status 401 # CLI (and library)
19
+ ```
20
+
21
+ Both packages are on PyPI, carry the same version and ship together from one tag
22
+ ([release](ops/README.md#release-to-pypi)). The plugin sends nothing until a test fails.
23
+
24
+ ## How a fact is verified
25
+
26
+ - One fact per YAML file in `facts/<service>/`, with a kind (`error_meaning`, `rate_limit`,
27
+ `breaking_change`, ...), the exact error signal, a one-sentence claim, dimensions (`env`, `plan`,
28
+ `region`, `account_state`) and evidence.
29
+ - Truth comes only from **deterministic probes**: declarative HTTP steps and assertions that our runner
30
+ executes on a schedule. No language model is called anywhere in the verification path.
31
+ - Fixes are **data, not advice**: members of a closed vocabulary with typed parameters (no free text, no
32
+ shell, no foreign URLs), rendered to one English sentence by us.
33
+ - A probe in another environment never refutes a fact; it adds a dimension.
34
+
35
+ ## Calling `check()`
36
+
37
+ One endpoint answers and learns at the same time: the request is the contribution. Send the target and,
38
+ optionally, the error you got; receive matching facts with typed fixes and what the probes observe. If
39
+ the target matches a registered template, a normalized observation is stored (no bodies, headers, query
40
+ strings or raw IPs).
41
+
42
+ ```bash
43
+ curl -s https://apifacts.dev/v0/check \
44
+ -H 'Content-Type: application/json' \
45
+ -d '{"target": {"method": "POST", "url": "https://api.stripe.com/v1/payment_intents"},
46
+ "error": {"status": 400, "body_excerpt": "Keys for idempotent requests can only be used with the same parameters they were first used with."}}'
47
+ ```
48
+
49
+ The response is never empty: `facts`, `observed`, and an `unknown.reason` when nothing matches.
50
+
51
+ ## Status
52
+
53
+ The API is live at https://apifacts.dev (`/v0/check`, `/v0/services`, `/openapi.json`, `/healthz`;
54
+ `facts.baillot.dev` is a legacy alias). The registry covers the services and facts listed in
55
+ [`pages/index.md`](pages/index.md), each fact page showing how it was established. Design contracts
56
+ live in [`docs/specs/`](docs/specs/README.md).
57
+
58
+ Running your own copy: the API reads `facts/` and `services/` once, at startup, so after a `git pull`
59
+ restart it; [`ops/deploy.sh`](ops/README.md#deploy) checks out, syncs and restarts in one step.
60
+
61
+ ## Contributing
62
+
63
+ Calling `check()` is contributing. Pull requests are for humans and API producers: see
64
+ [CONTRIBUTING.md](CONTRIBUTING.md). Producer signatures are always free.
65
+
66
+ ## License
67
+
68
+ Code: [MIT](LICENSE). Data (`facts/` and the generated fact pages): [CC BY 4.0](LICENSE-DATA).
@@ -0,0 +1,3 @@
1
+ """apifacts: verified facts about machine interfaces for AI agents."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,5 @@
1
+ """`check()` service: POST /v0/check (request = contribution), read endpoints, ingestion.
2
+
3
+ Spec: docs/specs/03-check-contract.md. Nothing here calls a model API or the network; the answer
4
+ comes from the facts in git, the observation is a normalized row in sqlite or nothing.
5
+ """