From fd0f044ae3a7f58cd99ae7d42f3b8b7a16342fed Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Tue, 22 Sep 2026 17:34:11 +0000 Subject: [PATCH 01/31] Add GeoIP and GeoLite web services spec Describe the GeoIP Country, City Plus, and Insights web services and the GeoLite Country and City services in OpenAPI 3.1. The schemas, descriptions, and examples follow the developer documentation. CI lints the specs with Redocly, which also checks each example against its schema, and checks that the committed bundle is current. The Go package embeds the bundles so services can validate their responses against them in tests. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/dependabot.yml | 25 + .github/workflows/ci.yml | 37 ++ .github/workflows/zizmor.yml | 27 + .gitignore | 1 + .precious.toml | 23 + .prettierrc.json | 3 + CHANGELOG.md | 5 + LICENSE-APACHE | 202 +++++++ LICENSE-MIT | 17 + README.md | 54 ++ bundled/geoip.yaml | 967 ++++++++++++++++++++++++++++++++++ components/errors.yaml | 24 + components/geoip-records.yaml | 556 +++++++++++++++++++ examples/geoip/city.yaml | 95 ++++ examples/geoip/country.yaml | 57 ++ examples/geoip/insights.yaml | 125 +++++ go.mod | 3 + mise.lock | 93 ++++ mise.toml | 8 + openapi.go | 11 + package.json | 14 + pnpm-lock.yaml | 34 ++ redocly.yaml | 17 + specs/geoip.yaml | 315 +++++++++++ 24 files changed, 2713 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/zizmor.yml create mode 100644 .gitignore create mode 100644 .precious.toml create mode 100644 .prettierrc.json create mode 100644 CHANGELOG.md create mode 100644 LICENSE-APACHE create mode 100644 LICENSE-MIT create mode 100644 README.md create mode 100644 bundled/geoip.yaml create mode 100644 components/errors.yaml create mode 100644 components/geoip-records.yaml create mode 100644 examples/geoip/city.yaml create mode 100644 examples/geoip/country.yaml create mode 100644 examples/geoip/insights.yaml create mode 100644 go.mod create mode 100644 mise.lock create mode 100644 mise.toml create mode 100644 openapi.go create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 redocly.yaml create mode 100644 specs/geoip.yaml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..121e8ed --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,25 @@ +version: 2 +updates: + - package-ecosystem: npm + directory: / + schedule: + interval: weekly + day: monday + time: "14:00" + groups: + minor-and-patch: + patterns: + - "*" + update-types: + - minor + - patch + cooldown: + default-days: 7 + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + day: monday + time: "14:00" + cooldown: + default-days: 7 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..aa7bc2a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,37 @@ +name: CI +permissions: + contents: read + +on: + push: + branches: + - main + pull_request: + workflow_dispatch: + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup mise + uses: jdx/mise-action@3c2e0cf82a5b2e5249f0d3635a4d83d0ae861518 # v4.2.5 + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Lint files + run: precious lint --all + + - name: Check that the bundles are current + run: | + pnpm run bundle + git add --intent-to-add bundled/ + git diff --exit-code bundled/ + + - name: Vet the Go package + run: go vet ./... diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 0000000..46bc8e2 --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,27 @@ +name: GitHub Actions Security Analysis with zizmor + +on: + push: + branches: ["main"] + pull_request: + branches: ["**"] + +permissions: {} + +jobs: + zizmor: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Run zizmor + uses: zizmorcore/zizmor-action@3dc1ecc9bcb9e94e9b2c709687979e1298497054 # v0.6.2 + with: + # Report findings in the job log instead of uploading them to code + # scanning. + advanced-security: false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/.precious.toml b/.precious.toml new file mode 100644 index 0000000..531af9a --- /dev/null +++ b/.precious.toml @@ -0,0 +1,23 @@ +[commands.prettier] +type = "both" +include = ["**/*.{json,md,yaml,yml}"] +exclude = ["bundled/**", "pnpm-lock.yaml"] +cmd = ["pnpm", "exec", "prettier"] +invoke = "once" +path-args = "absolute-file" +lint-flags = ["--check"] +tidy-flags = ["--write"] +ok-exit-codes = 0 +lint-failure-exit-codes = 1 +ignore-stderr = ["Code style issues"] + +[commands.redocly] +type = "lint" +include = ["specs/**", "components/**", "examples/**", "redocly.yaml"] +cmd = ["pnpm", "exec", "redocly", "lint"] +invoke = "once" +path-args = "none" +ok-exit-codes = 0 +lint-failure-exit-codes = 1 +# Redocly writes its progress to stderr. The exit code reports lint failures. +ignore-stderr = ["validated in"] diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..5b5bd99 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "proseWrap": "always" +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ce89b1f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## 0.1.0 + +- Add the GeoIP and GeoLite web services spec. diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..62589ed --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..f85e365 --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..59b0392 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# MaxMind OpenAPI specifications + +This repository holds [OpenAPI 3.1](https://spec.openapis.org/oas/v3.1.2) +descriptions of the MaxMind public web services. + +| Product | Bundled spec | Documentation | +| ------------------------------ | ------------------------------------------ | ------------------------------------------------------------------- | +| GeoIP and GeoLite web services | [`bundled/geoip.yaml`](bundled/geoip.yaml) | [dev.maxmind.com](https://dev.maxmind.com/geoip/docs/web-services/) | + +Each file in `bundled/` is self-contained. Use it with API tools and code +generators. The files in `specs/`, `components/`, and `examples/` are the +sources. Do not edit `bundled/` by hand. + +The [developer documentation](https://dev.maxmind.com/) is the reference for +behavior that OpenAPI cannot describe. MaxMind also publishes official +[client libraries](https://dev.maxmind.com/geoip/docs/web-services/#official-client-apis). + +## Compatibility + +MaxMind can add response fields, error codes, and enum values to response fields +without a new API version. Your client must ignore fields that it does not know. + +## Versioning + +The `info.version` of each spec follows +[Semantic Versioning](https://semver.org/) and tracks changes to the spec. The +API version, for example `v2.1`, is in the server URL. + +## Go + +The `github.com/maxmind/openapi` Go package embeds the bundled specs: + +```go +spec, err := openapi.Bundled.ReadFile("bundled/geoip.yaml") +``` + +## Development + +The tools are pinned with [mise](https://mise.jdx.dev/). + +```sh +mise install +pnpm install +pnpm run bundle # regenerate bundled/ +precious lint --all # lint the specs and format the files +``` + +## License + +This software is Copyright (c) 2026 by MaxMind, Inc. + +This is free software, licensed under the +[Apache License, Version 2.0](LICENSE-APACHE) or the [MIT License](LICENSE-MIT), +at your option. diff --git a/bundled/geoip.yaml b/bundled/geoip.yaml new file mode 100644 index 0000000..bac4e11 --- /dev/null +++ b/bundled/geoip.yaml @@ -0,0 +1,967 @@ +openapi: 3.1.2 +info: + title: GeoIP and GeoLite web services + version: 0.1.0 + summary: IP geolocation and network data for an IPv4 or IPv6 address. + description: |- + The GeoIP web services return geolocation and network data for an IP address. GeoIP Country, GeoIP City Plus, and GeoIP Insights are available on `geoip.maxmind.com`. GeoLite Country and GeoLite City are available on `geolite.info`. + + If a key maps to an undefined or empty value, the response leaves out the key. This applies to top-level keys and to the keys of nested objects. + + MaxMind can add keys to a response without a version change. Clients must ignore keys that they do not know. + + A successful response has a `Content-Type` of `application/vnd.maxmind.com-+json; charset=UTF-8; version=2.1`, for example `application/vnd.maxmind.com-city+json; charset=UTF-8; version=2.1`. An error response has a `Content-Type` of `application/vnd.maxmind.com-error+json; charset=UTF-8; version=2.1`. + + MaxMind can add new values to an enumerated field, other than the fixed continent codes, and new locale codes. MaxMind can also add or remove error codes. Clients must handle any 4xx or 5xx status and check `Content-Type` before they decode an error body. + contact: + name: MaxMind support + url: https://support.maxmind.com/ + license: + name: Apache 2.0 or MIT + identifier: Apache-2.0 OR MIT + termsOfService: https://www.maxmind.com/en/terms-of-use +servers: + - url: https://geoip.maxmind.com/geoip/v2.1 + description: GeoIP web services + - url: https://geolite.info/geoip/v2.1 + description: GeoLite web services (Country and City only) + - url: https://sandbox.maxmind.com/geoip/v2.1 + description: GeoIP sandbox. Use a license key from a Sandbox account. The sandbox returns fixed test data for a small set of IP addresses. Other addresses return `IP_ADDRESS_NOT_FOUND`. +security: + - basicAuth: [] +tags: + - name: GeoIP + description: IP geolocation lookups. +externalDocs: + description: GeoIP web services documentation + url: https://dev.maxmind.com/geoip/docs/web-services/ +paths: + /country/{ip_address}: + get: + operationId: getCountry + summary: Look up country data + description: Returns GeoIP Country data for the IP address. On `geolite.info`, this returns GeoLite Country data. + tags: + - GeoIP + parameters: + - $ref: '#/components/parameters/IPAddress' + - $ref: '#/components/parameters/Pretty' + responses: + '200': + description: The Country record for the IP address. + content: + application/vnd.maxmind.com-country+json: + schema: + $ref: '#/components/schemas/CountryResponse' + examples: + country: + $ref: '#/components/examples/country' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '402': + $ref: '#/components/responses/PaymentRequired' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalServerError' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /city/{ip_address}: + get: + operationId: getCity + summary: Look up city data + description: Returns GeoIP City Plus data for the IP address. On `geolite.info`, this returns GeoLite City data. + tags: + - GeoIP + parameters: + - $ref: '#/components/parameters/IPAddress' + - $ref: '#/components/parameters/Pretty' + responses: + '200': + description: The City record for the IP address. + content: + application/vnd.maxmind.com-city+json: + schema: + $ref: '#/components/schemas/CityResponse' + examples: + city: + $ref: '#/components/examples/city' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '402': + $ref: '#/components/responses/PaymentRequired' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalServerError' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /insights/{ip_address}: + servers: + - url: https://geoip.maxmind.com/geoip/v2.1 + description: GeoIP web services + - url: https://sandbox.maxmind.com/geoip/v2.1 + description: GeoIP sandbox. Use a license key from a Sandbox account. The sandbox returns fixed test data for a small set of IP addresses. Other addresses return `IP_ADDRESS_NOT_FOUND`. + get: + operationId: getInsights + summary: Look up insights data + description: Returns GeoIP Insights data for the IP address. GeoLite does not offer this service. + tags: + - GeoIP + parameters: + - $ref: '#/components/parameters/IPAddress' + - $ref: '#/components/parameters/Pretty' + responses: + '200': + description: The Insights record for the IP address. + content: + application/vnd.maxmind.com-insights+json: + schema: + $ref: '#/components/schemas/InsightsResponse' + examples: + insights: + $ref: '#/components/examples/insights' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '402': + $ref: '#/components/responses/PaymentRequired' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalServerError' + '503': + $ref: '#/components/responses/ServiceUnavailable' +components: + securitySchemes: + basicAuth: + type: http + scheme: basic + description: The username is your MaxMind account ID. The password is your MaxMind license key. The service accepts HTTPS requests only, with TLS 1.2 or higher. + parameters: + IPAddress: + name: ip_address + in: path + required: true + description: The IPv4 or IPv6 address to look up. Use the lowercase string `me` to look up the IP address that sends the request. For IPv6, the canonical form in RFC 5952 is recommended, but any valid form without a zone ID is accepted. + schema: + type: string + examples: + ipv4: + value: 1.2.3.4 + ipv6: + value: 2001:db8::1:0:0:1 + me: + value: me + Pretty: + name: pretty + in: query + required: false + description: If present, the response body is indented for reading, for example `?pretty`. + schema: + type: string + responses: + BadRequest: + description: |- + The request is not valid. The `code` is one of: + - `IP_ADDRESS_REQUIRED`: the request has an empty IP address. + - `IP_ADDRESS_INVALID`: the IP address is not a valid IPv4 or IPv6 address. + - `IP_ADDRESS_RESERVED`: the IP address is in a reserved or private range. + - `SERVICE_INVALID`: the service is not available on this host. On `geolite.info`, only Country and City are available. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + example: + code: IP_ADDRESS_RESERVED + error: You have supplied an IP address which belongs to a reserved or private range. + Unauthorized: + description: |- + The credentials are missing or not valid. The `code` is one of: + - `AUTHORIZATION_INVALID`: the account ID or license key is not valid. + - `ACCOUNT_ID_REQUIRED`: the Basic credentials have no account ID. + - `LICENSE_KEY_REQUIRED`: the Basic credentials have no license key. + headers: + WWW-Authenticate: + description: The authentication scheme, `Basic realm="geoip2"`. + schema: + type: string + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + example: + code: AUTHORIZATION_INVALID + error: Your account ID or license key could not be authenticated. + PaymentRequired: + description: The account has no funds for this service (`INSUFFICIENT_FUNDS`). For GeoLite, `INSUFFICIENT_FUNDS` means the account used its daily query limit. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + example: + code: INSUFFICIENT_FUNDS + error: You do not have sufficient funds to use this service. + Forbidden: + description: The account does not have permission to use this service (`PERMISSION_REQUIRED`). A request that uses HTTP instead of HTTPS also gets this status, but without a JSON body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + example: + code: PERMISSION_REQUIRED + error: You do not have permission to use the service. + NotFound: + description: The IP address is not in the database (`IP_ADDRESS_NOT_FOUND`). Some 404 responses do not have a JSON body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + example: + code: IP_ADDRESS_NOT_FOUND + error: The IP address '1.2.3.4' is not in our database. + TooManyRequests: + description: MaxMind rate-limited the request, usually because of too many earlier error responses. The response may have no body. + InternalServerError: + description: The service had an unexpected error (`SERVER_ERROR`). The response may have no body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + example: + code: SERVER_ERROR + error: There was an error when processing this request. + ServiceUnavailable: + description: The service has a temporary problem. Send the request again later. The response does not have a JSON body. + schemas: + Names: + type: object + description: 'A map from a locale code to the localized name for the entity. Known locale codes: de, en, es, fr, ja, pt-BR, ru, zh-CN. If the entity has name data, en is present. No other locale is guaranteed. Names can change between releases. Do not use them as keys. Use `geoname_id`, `iso_code`, or `code`.' + additionalProperties: + type: string + Continent: + type: object + description: The continent associated with an IP address. + properties: + code: + type: string + description: The two-character code for the continent. + enum: + - AF + - AN + - AS + - EU + - NA + - OC + - SA + geoname_id: + type: integer + minimum: 0 + description: The GeoNames ID for the continent. + names: + $ref: '#/components/schemas/Names' + Country: + type: object + description: A country associated with an IP address. + properties: + geoname_id: + type: integer + minimum: 0 + description: The GeoNames ID for the country. + iso_code: + type: string + description: The two-character ISO 3166-1 country code. + is_in_european_union: + type: boolean + description: True if the country is a member state of the European Union. + names: + $ref: '#/components/schemas/Names' + MaxMind: + type: object + description: Information about your MaxMind account. + properties: + queries_remaining: + type: integer + minimum: 0 + description: The approximate number of queries left for the endpoint you called. The GeoLite City web service does not include this field. + RepresentedCountry: + description: The country represented by users of an IP address, for example the country represented by an overseas military base. + allOf: + - $ref: '#/components/schemas/Country' + - type: object + properties: + type: + type: string + description: 'The type of represented country. Known value: military. MaxMind may add other values.' + CountryTraits: + type: object + description: General traits for an IP address, as returned by the Country response. + required: + - ip_address + - network + properties: + ip_address: + type: string + description: The IPv4 or IPv6 address that was looked up. + is_anycast: + type: boolean + description: True if the IP address belongs to an anycast network. + network: + type: string + description: The largest network, in CIDR notation, that shares the same data as this record, apart from `ip_address` itself. + CountryResponse: + type: object + required: + - traits + description: The GeoIP Country response. + properties: + continent: + $ref: '#/components/schemas/Continent' + description: The continent for the IP address. + country: + $ref: '#/components/schemas/Country' + description: The country where MaxMind believes the IP address's user is located. + maxmind: + $ref: '#/components/schemas/MaxMind' + registered_country: + $ref: '#/components/schemas/Country' + description: The country where the ISP registered the IP address. + represented_country: + $ref: '#/components/schemas/RepresentedCountry' + traits: + $ref: '#/components/schemas/CountryTraits' + description: General traits for the IP address. + Error: + type: object + description: Not all error responses have a JSON body. Check the `Content-Type` header before you decode the body as JSON. + required: + - code + - error + properties: + code: + type: string + description: A static error code for machine use. The meaning of a code never changes, but MaxMind can add or remove codes. + examples: + - IP_ADDRESS_INVALID + error: + type: string + description: A human-readable description of the error. The text can change at any time. + examples: + - The value '1.2.3' is not a valid IP address. + City: + type: object + description: The city associated with an IP address. + properties: + geoname_id: + type: integer + minimum: 0 + description: The GeoNames ID for the city. + names: + $ref: '#/components/schemas/Names' + Location: + type: object + description: Location details for an IP address. + properties: + accuracy_radius: + type: integer + minimum: 0 + description: The approximate accuracy radius, in kilometers, around the latitude and longitude. MaxMind has 67% confidence that the true location falls within this radius of the coordinates. + latitude: + type: number + minimum: -90 + maximum: 90 + description: The approximate WGS 84 latitude for the location. The coordinates are not precise. Do not use them to identify a street address or household. When you show the coordinates, also show `accuracy_radius`. + longitude: + type: number + minimum: -180 + maximum: 180 + description: The approximate WGS 84 longitude for the location. The coordinates are not precise. Do not use them to identify a street address or household. When you show the coordinates, also show `accuracy_radius`. + metro_code: + type: integer + minimum: 0 + deprecated: true + description: Deprecated. A code that Google previously used to target ads. MaxMind no longer maintains this code. + time_zone: + type: string + description: The IANA time zone for the location, for example `America/New_York`. + Postal: + type: object + description: The postal code associated with an IP address. + properties: + code: + type: string + description: 'A postal code close to the IP address''s location. For some countries, MaxMind returns only part of the code, with this many characters: Brazil 5, Canada 3, Ireland 3, Japan 7, Netherlands 4, Portugal 7, Singapore 2, United Kingdom 2-4, United States 5. For Japan, the last digit defaults to 1. For Portugal, the last 3 digits often default to `-001`.' + Subdivision: + type: object + description: A subdivision of the country associated with an IP address. + properties: + geoname_id: + type: integer + minimum: 0 + description: The GeoNames ID for the subdivision. + iso_code: + type: string + description: Up to three characters from the ISO 3166-2 code for the subdivision. + names: + $ref: '#/components/schemas/Names' + CityTraits: + description: General traits for an IP address, including the fields the City Plus response adds beyond Country. + allOf: + - $ref: '#/components/schemas/CountryTraits' + - type: object + properties: + autonomous_system_number: + type: integer + minimum: 0 + description: The autonomous system number for the IP address. + autonomous_system_organization: + type: string + description: The organization for the autonomous system number. + connection_type: + type: string + description: 'The connection type for the IP address. Known values: `Cable/DSL`, `Cellular`, `Corporate`, `Satellite`. MaxMind may add values. GeoLite City does not include this field.' + domain: + type: string + description: The second-level domain for the IP address, for example `example.com`. This is not a subdomain such as `foo.example.com`. GeoLite City does not include this field. + isp: + type: string + description: The ISP for the IP address. GeoLite City does not include this field. + mobile_country_code: + type: string + description: The mobile country code (MCC) for the IP address and ISP. GeoLite City does not include this field. + mobile_network_code: + type: string + description: The mobile network code (MNC) for the IP address and ISP. GeoLite City does not include this field. + organization: + type: string + description: The organization for the IP address. GeoLite City does not include this field. + CityResponse: + type: object + required: + - traits + description: The GeoIP City Plus response. + properties: + city: + $ref: '#/components/schemas/City' + description: The city for the IP address. + continent: + $ref: '#/components/schemas/Continent' + description: The continent for the IP address. + country: + $ref: '#/components/schemas/Country' + description: The country where MaxMind believes the IP address's user is located. + location: + $ref: '#/components/schemas/Location' + description: Location details for the IP address. + maxmind: + $ref: '#/components/schemas/MaxMind' + postal: + $ref: '#/components/schemas/Postal' + description: The postal code for the IP address. + registered_country: + $ref: '#/components/schemas/Country' + description: The country where the ISP registered the IP address. + represented_country: + $ref: '#/components/schemas/RepresentedCountry' + subdivisions: + type: array + description: The subdivisions of the country associated with the IP address, ordered from largest to smallest. + items: + $ref: '#/components/schemas/Subdivision' + traits: + $ref: '#/components/schemas/CityTraits' + description: General traits for the IP address. + AnonymizerResidential: + type: object + description: Data about the residential proxy network associated with an IP address. Only in the Insights response. + properties: + confidence: + type: integer + minimum: 1 + maximum: 99 + description: MaxMind's confidence that the network is an actively used residential proxy, from 1 to 99. + network_last_seen: + type: string + format: date + description: The last date MaxMind saw the network in its residential proxy analysis. + provider_name: + type: string + description: The name of the residential proxy provider, for example `oxylabs`. MaxMind identifies only a subset of residential proxy providers. + Anonymizer: + type: object + description: Whether an IP address is part of an anonymizing service or network. Only in the Insights response. + properties: + confidence: + type: integer + minimum: 1 + maximum: 99 + description: MaxMind's confidence that the network is an actively used VPN, from 1 to 99. MaxMind currently returns only 30 or 99, and will add more values over time. + is_anonymous: + type: boolean + description: True if the IP address belongs to any anonymous network. + is_anonymous_vpn: + type: boolean + description: True if the IP address belongs to an anonymous VPN provider. Some VPN providers register their ranges under other names, so MaxMind may flag them with `is_hosting_provider` instead. + is_hosting_provider: + type: boolean + description: True if the IP address belongs to a hosting provider. + is_public_proxy: + type: boolean + description: True if the IP address belongs to a public proxy. + is_residential_proxy: + type: boolean + description: True if the IP address is on a suspected anonymizing network and belongs to a residential ISP. This excludes peer-to-peer proxy IP addresses. + is_tor_exit_node: + type: boolean + description: True if the IP address is a Tor exit node. + network_last_seen: + type: string + format: date + description: The last date MaxMind saw the network in its anonymizer analysis. + provider_name: + type: string + description: The name of the VPN provider, for example `nordvpn`. MaxMind identifies only a subset of VPN providers. + residential: + $ref: '#/components/schemas/AnonymizerResidential' + CityWithConfidence: + description: A city associated with an IP address, with MaxMind's confidence in the result. Only the Insights response's `city` object includes `confidence`. + allOf: + - $ref: '#/components/schemas/City' + - type: object + properties: + confidence: + type: integer + minimum: 0 + maximum: 100 + description: MaxMind's confidence that the city is correct, from 0 to 100. + CountryWithConfidence: + description: A country associated with an IP address, with MaxMind's confidence in the result. Only the Insights response's `country` object includes `confidence`. + allOf: + - $ref: '#/components/schemas/Country' + - type: object + properties: + confidence: + type: integer + minimum: 0 + maximum: 100 + description: MaxMind's confidence that the country is correct, from 0 to 100. + InsightsLocation: + description: Location details for an IP address, including the fields the Insights response adds beyond City Plus. + allOf: + - $ref: '#/components/schemas/Location' + - type: object + properties: + average_income: + type: integer + minimum: 0 + description: The average annual income, in US dollars, for the IP address's location. Only available for IP addresses in the US. + population_density: + type: integer + minimum: 0 + description: The estimated number of people per square kilometer at the IP address's location. Only available for IP addresses in the US. + PostalWithConfidence: + description: A postal code associated with an IP address, with MaxMind's confidence in the result. Only the Insights response's `postal` object includes `confidence`. + allOf: + - $ref: '#/components/schemas/Postal' + - type: object + properties: + confidence: + type: integer + minimum: 0 + maximum: 100 + description: MaxMind's confidence that the postal code is correct, from 0 to 100. + SubdivisionWithConfidence: + description: A subdivision of the country associated with an IP address, with MaxMind's confidence in the result. Only the Insights response's `subdivisions` entries include `confidence`. + allOf: + - $ref: '#/components/schemas/Subdivision' + - type: object + properties: + confidence: + type: integer + minimum: 0 + maximum: 100 + description: MaxMind's confidence that the subdivision is correct, from 0 to 100. + InsightsTraits: + description: General traits for an IP address, including the fields the Insights response adds beyond City Plus. + allOf: + - $ref: '#/components/schemas/CityTraits' + - type: object + properties: + ip_risk_snapshot: + type: number + minimum: 0.01 + maximum: 99 + description: A snapshot of the risk for the IP address, from 0.01 to 99. A higher value means higher risk. This score changes less often than the equivalent minFraud score and does not respond to traffic on your network. MaxMind omits this field when it has no signals for the network or when the signals show the network is low risk. + is_anonymous: + type: boolean + deprecated: true + description: Deprecated. True if the IP address belongs to any anonymous network. Moved to the `anonymizer` object. Kept here for backward compatibility. + is_anonymous_vpn: + type: boolean + deprecated: true + description: Deprecated. True if the IP address belongs to an anonymous VPN provider. Moved to the `anonymizer` object. Kept here for backward compatibility. + is_hosting_provider: + type: boolean + deprecated: true + description: Deprecated. True if the IP address belongs to a hosting provider. Moved to the `anonymizer` object. Kept here for backward compatibility. + is_public_proxy: + type: boolean + deprecated: true + description: Deprecated. True if the IP address belongs to a public proxy. Moved to the `anonymizer` object. Kept here for backward compatibility. + is_residential_proxy: + type: boolean + deprecated: true + description: Deprecated. True if the IP address is on a suspected anonymizing network and belongs to a residential ISP. This excludes peer-to-peer proxy IP addresses. Moved to the `anonymizer` object. Kept here for backward compatibility. + is_tor_exit_node: + type: boolean + deprecated: true + description: Deprecated. True if the IP address is a Tor exit node. Moved to the `anonymizer` object. Kept here for backward compatibility. + static_ip_score: + type: number + minimum: 0 + maximum: 99.99 + description: How static the IP address is, from 0 to 99.99. A higher value means a more static address. + user_count: + type: integer + minimum: 0 + description: The estimated number of users on the IP address or network in the past 24 hours. For IPv4, this counts the single IP address. For IPv6, this counts the /64 network. + user_type: + type: string + description: 'The user type for the IP address. Known values: `business`, `cafe`, `cellular`, `college`, `consumer_privacy_network`, `content_delivery_network`, `government`, `hosting`, `library`, `military`, `residential`, `router`, `school`, `search_engine_spider`, `traveler`.' + InsightsResponse: + type: object + required: + - traits + description: The GeoIP Insights response. + properties: + anonymizer: + $ref: '#/components/schemas/Anonymizer' + description: Anonymizer data for the IP address. + city: + $ref: '#/components/schemas/CityWithConfidence' + description: The city for the IP address. + continent: + $ref: '#/components/schemas/Continent' + description: The continent for the IP address. + country: + $ref: '#/components/schemas/CountryWithConfidence' + description: The country where MaxMind believes the IP address's user is located. + location: + $ref: '#/components/schemas/InsightsLocation' + description: Location details for the IP address. + maxmind: + $ref: '#/components/schemas/MaxMind' + postal: + $ref: '#/components/schemas/PostalWithConfidence' + description: The postal code for the IP address. + registered_country: + $ref: '#/components/schemas/Country' + description: The country where the ISP registered the IP address. + represented_country: + $ref: '#/components/schemas/RepresentedCountry' + subdivisions: + type: array + description: The subdivisions of the country associated with the IP address, ordered from largest to smallest. + items: + $ref: '#/components/schemas/SubdivisionWithConfidence' + traits: + $ref: '#/components/schemas/InsightsTraits' + description: General traits for the IP address. + examples: + country: + summary: GeoIP Country response + value: + continent: + code: NA + geoname_id: 123456 + names: + de: Nordamerika + en: North America + es: América del Norte + fr: Amérique du Nord + ja: 北アメリカ + pt-BR: América do Norte + ru: Северная Америка + zh-CN: 北美洲 + country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + maxmind: + queries_remaining: 54321 + registered_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + represented_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + type: military + traits: + ip_address: 1.2.3.4 + is_anycast: true + network: 1.2.3.0/24 + city: + summary: GeoIP City Plus response + value: + continent: + code: NA + geoname_id: 123456 + names: + de: Nordamerika + en: North America + es: América del Norte + fr: Amérique du Nord + ja: 北アメリカ + pt-BR: América do Norte + ru: Северная Америка + zh-CN: 北美洲 + country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + maxmind: + queries_remaining: 54321 + registered_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + represented_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + type: military + traits: + ip_address: 1.2.3.4 + is_anycast: true + network: 1.2.3.0/24 + autonomous_system_number: 1239 + autonomous_system_organization: Linkem IR WiMax Network + connection_type: Cable/DSL + domain: example.com + isp: Linkem spa + mobile_country_code: '310' + mobile_network_code: '004' + organization: Linkem IR WiMax Network + city: + geoname_id: 54321 + names: + de: Los Angeles + en: Los Angeles + es: Los Ángeles + fr: Los Angeles + ja: ロサンゼルス市 + pt-BR: Los Angeles + ru: Лос-Анджелес + zh-CN: 洛杉矶 + location: + accuracy_radius: 20 + latitude: 37.6293 + longitude: -122.1163 + metro_code: 807 + time_zone: America/Los_Angeles + postal: + code: '90001' + subdivisions: + - geoname_id: 5332921 + iso_code: CA + names: + de: Kalifornien + en: California + es: California + fr: Californie + ja: カリフォルニア + ru: Калифорния + zh-CN: 加州 + insights: + summary: GeoIP Insights response + value: + continent: + code: NA + geoname_id: 123456 + names: + de: Nordamerika + en: North America + es: América del Norte + fr: Amérique du Nord + ja: 北アメリカ + pt-BR: América do Norte + ru: Северная Америка + zh-CN: 北美洲 + country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + confidence: 75 + maxmind: + queries_remaining: 54321 + registered_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + represented_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + type: military + anonymizer: + confidence: 99 + is_anonymous: true + is_anonymous_vpn: true + is_hosting_provider: true + is_public_proxy: true + is_residential_proxy: true + is_tor_exit_node: true + network_last_seen: '2025-01-15' + provider_name: nordvpn + residential: + confidence: 82 + network_last_seen: '2026-05-11' + provider_name: quickshift + traits: + ip_address: 1.2.3.4 + ip_risk_snapshot: 45.5 + is_anycast: true + network: 1.2.3.0/24 + autonomous_system_number: 1239 + autonomous_system_organization: Linkem IR WiMax Network + connection_type: Cable/DSL + domain: example.com + isp: Linkem spa + mobile_country_code: '310' + mobile_network_code: '004' + organization: Linkem IR WiMax Network + is_anonymous: true + is_anonymous_vpn: true + is_hosting_provider: true + is_public_proxy: true + is_residential_proxy: true + is_tor_exit_node: true + static_ip_score: 1.5 + user_count: 1 + user_type: traveler + city: + confidence: 25 + geoname_id: 54321 + names: + de: Los Angeles + en: Los Angeles + es: Los Ángeles + fr: Los Angeles + ja: ロサンゼルス市 + pt-BR: Los Angeles + ru: Лос-Анджелес + zh-CN: 洛杉矶 + location: + accuracy_radius: 20 + latitude: 37.6293 + longitude: -122.1163 + metro_code: 807 + time_zone: America/Los_Angeles + average_income: 128321 + population_density: 1234 + postal: + code: '90001' + confidence: 10 + subdivisions: + - geoname_id: 5332921 + iso_code: CA + names: + de: Kalifornien + en: California + es: California + fr: Californie + ja: カリフォルニア + ru: Калифорния + zh-CN: 加州 + confidence: 50 diff --git a/components/errors.yaml b/components/errors.yaml new file mode 100644 index 0000000..ac56332 --- /dev/null +++ b/components/errors.yaml @@ -0,0 +1,24 @@ +schemas: + Error: + type: object + description: >- + Not all error responses have a JSON body. Check the `Content-Type` header + before you decode the body as JSON. + required: + - code + - error + properties: + code: + type: string + description: >- + A static error code for machine use. The meaning of a code never + changes, but MaxMind can add or remove codes. + examples: + - IP_ADDRESS_INVALID + error: + type: string + description: >- + A human-readable description of the error. The text can change at any + time. + examples: + - "The value '1.2.3' is not a valid IP address." diff --git a/components/geoip-records.yaml b/components/geoip-records.yaml new file mode 100644 index 0000000..7925105 --- /dev/null +++ b/components/geoip-records.yaml @@ -0,0 +1,556 @@ +schemas: + Names: + type: object + description: >- + A map from a locale code to the localized name for the entity. Known + locale codes: de, en, es, fr, ja, pt-BR, ru, zh-CN. If the entity has name + data, en is present. No other locale is guaranteed. Names can change + between releases. Do not use them as keys. Use `geoname_id`, `iso_code`, + or `code`. + additionalProperties: + type: string + Continent: + type: object + description: The continent associated with an IP address. + properties: + code: + type: string + description: The two-character code for the continent. + enum: + - AF + - AN + - AS + - EU + - NA + - OC + - SA + geoname_id: + type: integer + minimum: 0 + description: The GeoNames ID for the continent. + names: + $ref: "#/schemas/Names" + Country: + type: object + description: A country associated with an IP address. + properties: + geoname_id: + type: integer + minimum: 0 + description: The GeoNames ID for the country. + iso_code: + type: string + description: The two-character ISO 3166-1 country code. + is_in_european_union: + type: boolean + description: + True if the country is a member state of the European Union. + names: + $ref: "#/schemas/Names" + CountryWithConfidence: + description: >- + A country associated with an IP address, with MaxMind's confidence in the + result. Only the Insights response's `country` object includes + `confidence`. + allOf: + - $ref: "#/schemas/Country" + - type: object + properties: + confidence: + type: integer + minimum: 0 + maximum: 100 + description: + MaxMind's confidence that the country is correct, from 0 to 100. + RepresentedCountry: + description: >- + The country represented by users of an IP address, for example the country + represented by an overseas military base. + allOf: + - $ref: "#/schemas/Country" + - type: object + properties: + type: + type: string + description: >- + The type of represented country. Known value: military. MaxMind + may add other values. + City: + type: object + description: The city associated with an IP address. + properties: + geoname_id: + type: integer + minimum: 0 + description: The GeoNames ID for the city. + names: + $ref: "#/schemas/Names" + CityWithConfidence: + description: >- + A city associated with an IP address, with MaxMind's confidence in the + result. Only the Insights response's `city` object includes `confidence`. + allOf: + - $ref: "#/schemas/City" + - type: object + properties: + confidence: + type: integer + minimum: 0 + maximum: 100 + description: + MaxMind's confidence that the city is correct, from 0 to 100. + Postal: + type: object + description: The postal code associated with an IP address. + properties: + code: + type: string + description: >- + A postal code close to the IP address's location. For some countries, + MaxMind returns only part of the code, with this many characters: + Brazil 5, Canada 3, Ireland 3, Japan 7, Netherlands 4, Portugal 7, + Singapore 2, United Kingdom 2-4, United States 5. For Japan, the last + digit defaults to 1. For Portugal, the last 3 digits often default to + `-001`. + PostalWithConfidence: + description: >- + A postal code associated with an IP address, with MaxMind's confidence in + the result. Only the Insights response's `postal` object includes + `confidence`. + allOf: + - $ref: "#/schemas/Postal" + - type: object + properties: + confidence: + type: integer + minimum: 0 + maximum: 100 + description: >- + MaxMind's confidence that the postal code is correct, from 0 to + 100. + Subdivision: + type: object + description: A subdivision of the country associated with an IP address. + properties: + geoname_id: + type: integer + minimum: 0 + description: The GeoNames ID for the subdivision. + iso_code: + type: string + description: + Up to three characters from the ISO 3166-2 code for the subdivision. + names: + $ref: "#/schemas/Names" + SubdivisionWithConfidence: + description: >- + A subdivision of the country associated with an IP address, with MaxMind's + confidence in the result. Only the Insights response's `subdivisions` + entries include `confidence`. + allOf: + - $ref: "#/schemas/Subdivision" + - type: object + properties: + confidence: + type: integer + minimum: 0 + maximum: 100 + description: >- + MaxMind's confidence that the subdivision is correct, from 0 to + 100. + Location: + type: object + description: Location details for an IP address. + properties: + accuracy_radius: + type: integer + minimum: 0 + description: >- + The approximate accuracy radius, in kilometers, around the latitude + and longitude. MaxMind has 67% confidence that the true location falls + within this radius of the coordinates. + latitude: + type: number + minimum: -90 + maximum: 90 + description: >- + The approximate WGS 84 latitude for the location. The coordinates are + not precise. Do not use them to identify a street address or + household. When you show the coordinates, also show `accuracy_radius`. + longitude: + type: number + minimum: -180 + maximum: 180 + description: >- + The approximate WGS 84 longitude for the location. The coordinates are + not precise. Do not use them to identify a street address or + household. When you show the coordinates, also show `accuracy_radius`. + metro_code: + type: integer + minimum: 0 + deprecated: true + description: >- + Deprecated. A code that Google previously used to target ads. MaxMind + no longer maintains this code. + time_zone: + type: string + description: >- + The IANA time zone for the location, for example `America/New_York`. + InsightsLocation: + description: >- + Location details for an IP address, including the fields the Insights + response adds beyond City Plus. + allOf: + - $ref: "#/schemas/Location" + - type: object + properties: + average_income: + type: integer + minimum: 0 + description: >- + The average annual income, in US dollars, for the IP address's + location. Only available for IP addresses in the US. + population_density: + type: integer + minimum: 0 + description: >- + The estimated number of people per square kilometer at the IP + address's location. Only available for IP addresses in the US. + CountryTraits: + type: object + description: + General traits for an IP address, as returned by the Country response. + required: + - ip_address + - network + properties: + ip_address: + type: string + description: >- + The IPv4 or IPv6 address that was looked up. + is_anycast: + type: boolean + description: True if the IP address belongs to an anycast network. + network: + type: string + description: >- + The largest network, in CIDR notation, that shares the same data as + this record, apart from `ip_address` itself. + CityTraits: + description: >- + General traits for an IP address, including the fields the City Plus + response adds beyond Country. + allOf: + - $ref: "#/schemas/CountryTraits" + - type: object + properties: + autonomous_system_number: + type: integer + minimum: 0 + description: The autonomous system number for the IP address. + autonomous_system_organization: + type: string + description: The organization for the autonomous system number. + connection_type: + type: string + description: >- + The connection type for the IP address. Known values: `Cable/DSL`, + `Cellular`, `Corporate`, `Satellite`. MaxMind may add values. + GeoLite City does not include this field. + domain: + type: string + description: >- + The second-level domain for the IP address, for example + `example.com`. This is not a subdomain such as `foo.example.com`. + GeoLite City does not include this field. + isp: + type: string + description: >- + The ISP for the IP address. GeoLite City does not include this + field. + mobile_country_code: + type: string + description: >- + The mobile country code (MCC) for the IP address and ISP. GeoLite + City does not include this field. + mobile_network_code: + type: string + description: >- + The mobile network code (MNC) for the IP address and ISP. GeoLite + City does not include this field. + organization: + type: string + description: >- + The organization for the IP address. GeoLite City does not include + this field. + InsightsTraits: + description: >- + General traits for an IP address, including the fields the Insights + response adds beyond City Plus. + allOf: + - $ref: "#/schemas/CityTraits" + - type: object + properties: + ip_risk_snapshot: + type: number + minimum: 0.01 + maximum: 99 + description: >- + A snapshot of the risk for the IP address, from 0.01 to 99. A + higher value means higher risk. This score changes less often than + the equivalent minFraud score and does not respond to traffic on + your network. MaxMind omits this field when it has no signals for + the network or when the signals show the network is low risk. + is_anonymous: + type: boolean + deprecated: true + description: >- + Deprecated. True if the IP address belongs to any anonymous + network. Moved to the `anonymizer` object. Kept here for backward + compatibility. + is_anonymous_vpn: + type: boolean + deprecated: true + description: >- + Deprecated. True if the IP address belongs to an anonymous VPN + provider. Moved to the `anonymizer` object. Kept here for backward + compatibility. + is_hosting_provider: + type: boolean + deprecated: true + description: >- + Deprecated. True if the IP address belongs to a hosting provider. + Moved to the `anonymizer` object. Kept here for backward + compatibility. + is_public_proxy: + type: boolean + deprecated: true + description: >- + Deprecated. True if the IP address belongs to a public proxy. + Moved to the `anonymizer` object. Kept here for backward + compatibility. + is_residential_proxy: + type: boolean + deprecated: true + description: >- + Deprecated. True if the IP address is on a suspected anonymizing + network and belongs to a residential ISP. This excludes + peer-to-peer proxy IP addresses. Moved to the `anonymizer` object. + Kept here for backward compatibility. + is_tor_exit_node: + type: boolean + deprecated: true + description: >- + Deprecated. True if the IP address is a Tor exit node. Moved to + the `anonymizer` object. Kept here for backward compatibility. + static_ip_score: + type: number + minimum: 0 + maximum: 99.99 + description: >- + How static the IP address is, from 0 to 99.99. A higher value + means a more static address. + user_count: + type: integer + minimum: 0 + description: >- + The estimated number of users on the IP address or network in the + past 24 hours. For IPv4, this counts the single IP address. For + IPv6, this counts the /64 network. + user_type: + type: string + description: >- + The user type for the IP address. Known values: `business`, + `cafe`, `cellular`, `college`, `consumer_privacy_network`, + `content_delivery_network`, `government`, `hosting`, `library`, + `military`, `residential`, `router`, `school`, + `search_engine_spider`, `traveler`. + AnonymizerResidential: + type: object + description: >- + Data about the residential proxy network associated with an IP address. + Only in the Insights response. + properties: + confidence: + type: integer + minimum: 1 + maximum: 99 + description: >- + MaxMind's confidence that the network is an actively used residential + proxy, from 1 to 99. + network_last_seen: + type: string + format: date + description: >- + The last date MaxMind saw the network in its residential proxy + analysis. + provider_name: + type: string + description: >- + The name of the residential proxy provider, for example `oxylabs`. + MaxMind identifies only a subset of residential proxy providers. + Anonymizer: + type: object + description: >- + Whether an IP address is part of an anonymizing service or network. Only + in the Insights response. + properties: + confidence: + type: integer + minimum: 1 + maximum: 99 + description: >- + MaxMind's confidence that the network is an actively used VPN, from 1 + to 99. MaxMind currently returns only 30 or 99, and will add more + values over time. + is_anonymous: + type: boolean + description: True if the IP address belongs to any anonymous network. + is_anonymous_vpn: + type: boolean + description: >- + True if the IP address belongs to an anonymous VPN provider. Some VPN + providers register their ranges under other names, so MaxMind may flag + them with `is_hosting_provider` instead. + is_hosting_provider: + type: boolean + description: True if the IP address belongs to a hosting provider. + is_public_proxy: + type: boolean + description: True if the IP address belongs to a public proxy. + is_residential_proxy: + type: boolean + description: >- + True if the IP address is on a suspected anonymizing network and + belongs to a residential ISP. This excludes peer-to-peer proxy IP + addresses. + is_tor_exit_node: + type: boolean + description: True if the IP address is a Tor exit node. + network_last_seen: + type: string + format: date + description: + The last date MaxMind saw the network in its anonymizer analysis. + provider_name: + type: string + description: >- + The name of the VPN provider, for example `nordvpn`. MaxMind + identifies only a subset of VPN providers. + residential: + $ref: "#/schemas/AnonymizerResidential" + MaxMind: + type: object + description: >- + Information about your MaxMind account. + properties: + queries_remaining: + type: integer + minimum: 0 + description: >- + The approximate number of queries left for the endpoint you called. + The GeoLite City web service does not include this field. + CountryResponse: + type: object + required: + - traits + description: The GeoIP Country response. + properties: + continent: + $ref: "#/schemas/Continent" + description: The continent for the IP address. + country: + $ref: "#/schemas/Country" + description: + The country where MaxMind believes the IP address's user is located. + maxmind: + $ref: "#/schemas/MaxMind" + registered_country: + $ref: "#/schemas/Country" + description: The country where the ISP registered the IP address. + represented_country: + $ref: "#/schemas/RepresentedCountry" + traits: + $ref: "#/schemas/CountryTraits" + description: General traits for the IP address. + CityResponse: + type: object + required: + - traits + description: The GeoIP City Plus response. + properties: + city: + $ref: "#/schemas/City" + description: The city for the IP address. + continent: + $ref: "#/schemas/Continent" + description: The continent for the IP address. + country: + $ref: "#/schemas/Country" + description: + The country where MaxMind believes the IP address's user is located. + location: + $ref: "#/schemas/Location" + description: Location details for the IP address. + maxmind: + $ref: "#/schemas/MaxMind" + postal: + $ref: "#/schemas/Postal" + description: The postal code for the IP address. + registered_country: + $ref: "#/schemas/Country" + description: The country where the ISP registered the IP address. + represented_country: + $ref: "#/schemas/RepresentedCountry" + subdivisions: + type: array + description: >- + The subdivisions of the country associated with the IP address, + ordered from largest to smallest. + items: + $ref: "#/schemas/Subdivision" + traits: + $ref: "#/schemas/CityTraits" + description: General traits for the IP address. + InsightsResponse: + type: object + required: + - traits + description: The GeoIP Insights response. + properties: + anonymizer: + $ref: "#/schemas/Anonymizer" + description: Anonymizer data for the IP address. + city: + $ref: "#/schemas/CityWithConfidence" + description: The city for the IP address. + continent: + $ref: "#/schemas/Continent" + description: The continent for the IP address. + country: + $ref: "#/schemas/CountryWithConfidence" + description: + The country where MaxMind believes the IP address's user is located. + location: + $ref: "#/schemas/InsightsLocation" + description: Location details for the IP address. + maxmind: + $ref: "#/schemas/MaxMind" + postal: + $ref: "#/schemas/PostalWithConfidence" + description: The postal code for the IP address. + registered_country: + $ref: "#/schemas/Country" + description: The country where the ISP registered the IP address. + represented_country: + $ref: "#/schemas/RepresentedCountry" + subdivisions: + type: array + description: >- + The subdivisions of the country associated with the IP address, + ordered from largest to smallest. + items: + $ref: "#/schemas/SubdivisionWithConfidence" + traits: + $ref: "#/schemas/InsightsTraits" + description: General traits for the IP address. diff --git a/examples/geoip/city.yaml b/examples/geoip/city.yaml new file mode 100644 index 0000000..95ce032 --- /dev/null +++ b/examples/geoip/city.yaml @@ -0,0 +1,95 @@ +summary: GeoIP City Plus response +value: + continent: + code: NA + geoname_id: 123456 + names: + de: Nordamerika + en: North America + es: América del Norte + fr: Amérique du Nord + ja: 北アメリカ + pt-BR: América do Norte + ru: Северная Америка + zh-CN: 北美洲 + country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + maxmind: + queries_remaining: 54321 + registered_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + represented_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + type: military + traits: + ip_address: 1.2.3.4 + is_anycast: true + network: 1.2.3.0/24 + autonomous_system_number: 1239 + autonomous_system_organization: Linkem IR WiMax Network + connection_type: Cable/DSL + domain: example.com + isp: Linkem spa + mobile_country_code: "310" + mobile_network_code: "004" + organization: Linkem IR WiMax Network + city: + geoname_id: 54321 + names: + de: Los Angeles + en: Los Angeles + es: Los Ángeles + fr: Los Angeles + ja: ロサンゼルス市 + pt-BR: Los Angeles + ru: Лос-Анджелес + zh-CN: 洛杉矶 + location: + accuracy_radius: 20 + latitude: 37.6293 + longitude: -122.1163 + metro_code: 807 + time_zone: America/Los_Angeles + postal: + code: "90001" + subdivisions: + - geoname_id: 5332921 + iso_code: CA + names: + de: Kalifornien + en: California + es: California + fr: Californie + ja: カリフォルニア + ru: Калифорния + zh-CN: 加州 diff --git a/examples/geoip/country.yaml b/examples/geoip/country.yaml new file mode 100644 index 0000000..ea11367 --- /dev/null +++ b/examples/geoip/country.yaml @@ -0,0 +1,57 @@ +summary: GeoIP Country response +value: + continent: + code: NA + geoname_id: 123456 + names: + de: Nordamerika + en: North America + es: América del Norte + fr: Amérique du Nord + ja: 北アメリカ + pt-BR: América do Norte + ru: Северная Америка + zh-CN: 北美洲 + country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + maxmind: + queries_remaining: 54321 + registered_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + represented_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + type: military + traits: + ip_address: 1.2.3.4 + is_anycast: true + network: 1.2.3.0/24 diff --git a/examples/geoip/insights.yaml b/examples/geoip/insights.yaml new file mode 100644 index 0000000..7700af7 --- /dev/null +++ b/examples/geoip/insights.yaml @@ -0,0 +1,125 @@ +summary: GeoIP Insights response +value: + continent: + code: NA + geoname_id: 123456 + names: + de: Nordamerika + en: North America + es: América del Norte + fr: Amérique du Nord + ja: 北アメリカ + pt-BR: América do Norte + ru: Северная Америка + zh-CN: 北美洲 + country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + confidence: 75 + maxmind: + queries_remaining: 54321 + registered_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + represented_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + type: military + anonymizer: + confidence: 99 + is_anonymous: true + is_anonymous_vpn: true + is_hosting_provider: true + is_public_proxy: true + is_residential_proxy: true + is_tor_exit_node: true + network_last_seen: "2025-01-15" + provider_name: nordvpn + residential: + confidence: 82 + network_last_seen: "2026-05-11" + provider_name: quickshift + traits: + ip_address: 1.2.3.4 + ip_risk_snapshot: 45.5 + is_anycast: true + network: 1.2.3.0/24 + autonomous_system_number: 1239 + autonomous_system_organization: Linkem IR WiMax Network + connection_type: Cable/DSL + domain: example.com + isp: Linkem spa + mobile_country_code: "310" + mobile_network_code: "004" + organization: Linkem IR WiMax Network + is_anonymous: true + is_anonymous_vpn: true + is_hosting_provider: true + is_public_proxy: true + is_residential_proxy: true + is_tor_exit_node: true + static_ip_score: 1.5 + user_count: 1 + user_type: traveler + city: + confidence: 25 + geoname_id: 54321 + names: + de: Los Angeles + en: Los Angeles + es: Los Ángeles + fr: Los Angeles + ja: ロサンゼルス市 + pt-BR: Los Angeles + ru: Лос-Анджелес + zh-CN: 洛杉矶 + location: + accuracy_radius: 20 + latitude: 37.6293 + longitude: -122.1163 + metro_code: 807 + time_zone: America/Los_Angeles + average_income: 128321 + population_density: 1234 + postal: + code: "90001" + confidence: 10 + subdivisions: + - geoname_id: 5332921 + iso_code: CA + names: + de: Kalifornien + en: California + es: California + fr: Californie + ja: カリフォルニア + ru: Калифорния + zh-CN: 加州 + confidence: 50 diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..fa48555 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/maxmind/openapi + +go 1.25 diff --git a/mise.lock b/mise.lock new file mode 100644 index 0000000..f0c11af --- /dev/null +++ b/mise.lock @@ -0,0 +1,93 @@ +# @generated - this file is auto-generated by `mise lock` https://mise.jdx.dev/dev-tools/mise-lock.html + +lockfile_version = 1 + +[[tools."aqua:pnpm/pnpm"]] +version = "11.27.0" +backend = "aqua:pnpm/pnpm" +specifiers = ["11.27.0"] + +[tools."aqua:pnpm/pnpm"."platforms.linux-arm64"] +checksum = "sha256:1f3c5dbdfe20b011ea86950b4fd61b5918cbde874c099032fe9064f7a53816bf" +url = "https://github.com/pnpm/pnpm/releases/download/v11.27.0/pnpm-linux-arm64.tar.gz" +url_api = "https://api.github.com/repos/pnpm/pnpm/releases/assets/559064653" +provenance = "github-attestations" + +[tools."aqua:pnpm/pnpm"."platforms.linux-x64"] +checksum = "sha256:14ed04e631e4563abf3570dda1a365316683149a482b741a2db37e495f6b9cdb" +url = "https://github.com/pnpm/pnpm/releases/download/v11.27.0/pnpm-linux-x64.tar.gz" +url_api = "https://api.github.com/repos/pnpm/pnpm/releases/assets/559064655" +provenance = "github-attestations" + +[tools."aqua:pnpm/pnpm"."platforms.macos-arm64"] +checksum = "sha256:9e8724db1d733d651cfe9a55d6de3d59fc8c5e472b9b4e9c2844acafd38c015e" +url = "https://github.com/pnpm/pnpm/releases/download/v11.27.0/pnpm-darwin-arm64.tar.gz" +url_api = "https://api.github.com/repos/pnpm/pnpm/releases/assets/559064654" +provenance = "github-attestations" + +[[tools."github:houseabsolute/precious"]] +version = "0.11.0" +backend = "github:houseabsolute/precious" +specifiers = ["0.11.0"] + +[tools."github:houseabsolute/precious"."platforms.linux-arm64"] +checksum = "sha256:44d98091a988671786a99d8025b169c76bb08718ffa8f793a80ae1aa97ca5472" +url = "https://github.com/houseabsolute/precious/releases/download/v0.11.0/precious-Linux-musl-arm64.tar.gz" +url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/434639525" + +[tools."github:houseabsolute/precious"."platforms.linux-x64"] +checksum = "sha256:6a267a3e309ebd39ef36352e283b2ad70066ccb61e4b04785afbd85df3fa76b4" +url = "https://github.com/houseabsolute/precious/releases/download/v0.11.0/precious-Linux-musl-x86_64.tar.gz" +url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/434639494" + +[tools."github:houseabsolute/precious"."platforms.macos-arm64"] +checksum = "sha256:e6cbdba5261c15e3eb9208af928facff50c883bb11c0dd0c10766379285c75b9" +url = "https://github.com/houseabsolute/precious/releases/download/v0.11.0/precious-macOS-arm64.tar.gz" +url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/434639276" + +[tools."github:houseabsolute/precious"."platforms.macos-x64"] +checksum = "sha256:5500304c379686acd0cb852ad9f32e20baaab939f7fbc1f75f1ec0583f4bd676" +url = "https://github.com/houseabsolute/precious/releases/download/v0.11.0/precious-macOS-x86_64.tar.gz" +url_api = "https://api.github.com/repos/houseabsolute/precious/releases/assets/434639281" + +[[tools.go]] +version = "1.25.7" +backend = "core:go" +specifiers = ["1.25"] + +[tools.go."platforms.linux-arm64"] +checksum = "sha256:ba611a53534135a81067240eff9508cd7e256c560edd5d8c2fef54f083c07129" +url = "https://dl.google.com/go/go1.25.7.linux-arm64.tar.gz" + +[tools.go."platforms.linux-x64"] +checksum = "sha256:12e6d6a191091ae27dc31f6efc630e3a3b8ba409baf3573d955b196fdf086005" +url = "https://dl.google.com/go/go1.25.7.linux-amd64.tar.gz" + +[tools.go."platforms.macos-arm64"] +checksum = "sha256:ff18369ffad05c57d5bed888b660b31385f3c913670a83ef557cdfd98ea9ae1b" +url = "https://dl.google.com/go/go1.25.7.darwin-arm64.tar.gz" + +[tools.go."platforms.macos-x64"] +checksum = "sha256:bf5050a2152f4053837b886e8d9640c829dbacbc3370f913351eb0904cb706f5" +url = "https://dl.google.com/go/go1.25.7.darwin-amd64.tar.gz" + +[[tools.node]] +version = "24.21.0" +backend = "core:node" +specifiers = ["24"] + +[tools.node."platforms.linux-arm64"] +checksum = "sha256:724282c3b43aec998aa9527380465b45d229e021b58035f5f4f63095eabfe5d5" +url = "https://nodejs.org/dist/v24.21.0/node-v24.21.0-linux-arm64.tar.gz" + +[tools.node."platforms.linux-x64"] +checksum = "sha256:6e1db87ef58b8819e5d5402eff1536491b18edd8eb7bee5ef7897876e88dc5ff" +url = "https://nodejs.org/dist/v24.21.0/node-v24.21.0-linux-x64.tar.gz" + +[tools.node."platforms.macos-arm64"] +checksum = "sha256:bed7eea5325e1108f32ce5228ddd6a5f0f08a499ee42aa7442aea583702f6057" +url = "https://nodejs.org/dist/v24.21.0/node-v24.21.0-darwin-arm64.tar.gz" + +[tools.node."platforms.macos-x64"] +checksum = "sha256:1462cb3b3046b815cf8ea436d3da450ec1a9f11dac7e5a46b0ada5305d7e8097" +url = "https://nodejs.org/dist/v24.21.0/node-v24.21.0-darwin-x64.tar.gz" diff --git a/mise.toml b/mise.toml new file mode 100644 index 0000000..f21ae16 --- /dev/null +++ b/mise.toml @@ -0,0 +1,8 @@ +[settings] +lockfile = true + +[tools] +go = "1.25" +node = "24" +"aqua:pnpm/pnpm" = "11.27.0" +"github:houseabsolute/precious" = "0.11.0" diff --git a/openapi.go b/openapi.go new file mode 100644 index 0000000..87180fe --- /dev/null +++ b/openapi.go @@ -0,0 +1,11 @@ +// Package openapi embeds the bundled OpenAPI documents for the MaxMind web +// services, so Go programs can validate requests and responses against them. +package openapi + +import "embed" + +// Bundled holds one self-contained OpenAPI document per product, for example +// "bundled/geoip.yaml". +// +//go:embed bundled/*.yaml +var Bundled embed.FS diff --git a/package.json b/package.json new file mode 100644 index 0000000..399dda0 --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "maxmind-openapi", + "private": true, + "license": "Apache-2.0 OR MIT", + "type": "module", + "scripts": { + "bundle": "redocly bundle", + "lint": "redocly lint" + }, + "devDependencies": { + "@redocly/cli": "^2.53.3", + "prettier": "^3.9.8" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..4fc7077 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,34 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@redocly/cli': + specifier: ^2.53.3 + version: 2.53.3 + prettier: + specifier: ^3.9.8 + version: 3.9.8 + +packages: + + '@redocly/cli@2.53.3': + resolution: {integrity: sha512-hzNAWzHCOZ05vwRx0ehTxNeJaxxizjGV505eKtfs9MR/8ieD/8lYhAK4GF5FaqRRwOEpLO0PvzQwBSKYXmxhRA==} + engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'} + hasBin: true + + prettier@3.9.8: + resolution: {integrity: sha512-WRFq3Wn3WId7LLROfMLdH7xaFr2jR62wU8nLO6rQUOLOxNZUviyJQs1M0iIhLexSFy+L+w0ch66wtoO2jRjG0A==} + engines: {node: '>=14'} + hasBin: true + +snapshots: + + '@redocly/cli@2.53.3': {} + + prettier@3.9.8: {} diff --git a/redocly.yaml b/redocly.yaml new file mode 100644 index 0000000..c6d4de8 --- /dev/null +++ b/redocly.yaml @@ -0,0 +1,17 @@ +extends: + - recommended-strict + +rules: + # MaxMind APIs are served from fixed public hosts. + no-server-example.com: error + operation-4xx-response: error + # Response schemas allow unknown keys for forward compatibility, but every + # key in an example must still be declared. + no-invalid-media-type-examples: + severity: error + allowAdditionalProperties: false + +apis: + geoip: + root: specs/geoip.yaml + output: bundled/geoip.yaml diff --git a/specs/geoip.yaml b/specs/geoip.yaml new file mode 100644 index 0000000..53702e4 --- /dev/null +++ b/specs/geoip.yaml @@ -0,0 +1,315 @@ +openapi: 3.1.2 +info: + title: GeoIP and GeoLite web services + version: 0.1.0 + summary: IP geolocation and network data for an IPv4 or IPv6 address. + description: >- + The GeoIP web services return geolocation and network data for an IP + address. GeoIP Country, GeoIP City Plus, and GeoIP Insights are available on + `geoip.maxmind.com`. GeoLite Country and GeoLite City are available on + `geolite.info`. + + + If a key maps to an undefined or empty value, the response leaves out the + key. This applies to top-level keys and to the keys of nested objects. + + + MaxMind can add keys to a response without a version change. Clients must + ignore keys that they do not know. + + + A successful response has a `Content-Type` of + `application/vnd.maxmind.com-+json; charset=UTF-8; version=2.1`, + for example `application/vnd.maxmind.com-city+json; charset=UTF-8; + version=2.1`. An error response has a `Content-Type` of + `application/vnd.maxmind.com-error+json; charset=UTF-8; version=2.1`. + + + MaxMind can add new values to an enumerated field, other than the fixed + continent codes, and new locale codes. MaxMind can also add or remove error + codes. Clients must handle any 4xx or 5xx status and check `Content-Type` + before they decode an error body. + contact: + name: MaxMind support + url: https://support.maxmind.com/ + license: + name: Apache 2.0 or MIT + identifier: Apache-2.0 OR MIT + termsOfService: https://www.maxmind.com/en/terms-of-use +externalDocs: + description: GeoIP web services documentation + url: https://dev.maxmind.com/geoip/docs/web-services/ +servers: + - url: https://geoip.maxmind.com/geoip/v2.1 + description: GeoIP web services + - url: https://geolite.info/geoip/v2.1 + description: GeoLite web services (Country and City only) + - url: https://sandbox.maxmind.com/geoip/v2.1 + description: >- + GeoIP sandbox. Use a license key from a Sandbox account. The sandbox + returns fixed test data for a small set of IP addresses. Other addresses + return `IP_ADDRESS_NOT_FOUND`. +security: + - basicAuth: [] +tags: + - name: GeoIP + description: IP geolocation lookups. +paths: + /country/{ip_address}: + get: + operationId: getCountry + summary: Look up country data + description: >- + Returns GeoIP Country data for the IP address. On `geolite.info`, this + returns GeoLite Country data. + tags: + - GeoIP + parameters: + - $ref: "#/components/parameters/IPAddress" + - $ref: "#/components/parameters/Pretty" + responses: + "200": + description: The Country record for the IP address. + content: + application/vnd.maxmind.com-country+json: + schema: + $ref: "../components/geoip-records.yaml#/schemas/CountryResponse" + examples: + country: + $ref: "../examples/geoip/country.yaml" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "402": + $ref: "#/components/responses/PaymentRequired" + "403": + $ref: "#/components/responses/Forbidden" + "404": + $ref: "#/components/responses/NotFound" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalServerError" + "503": + $ref: "#/components/responses/ServiceUnavailable" + /city/{ip_address}: + get: + operationId: getCity + summary: Look up city data + description: >- + Returns GeoIP City Plus data for the IP address. On `geolite.info`, this + returns GeoLite City data. + tags: + - GeoIP + parameters: + - $ref: "#/components/parameters/IPAddress" + - $ref: "#/components/parameters/Pretty" + responses: + "200": + description: The City record for the IP address. + content: + application/vnd.maxmind.com-city+json: + schema: + $ref: "../components/geoip-records.yaml#/schemas/CityResponse" + examples: + city: + $ref: "../examples/geoip/city.yaml" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "402": + $ref: "#/components/responses/PaymentRequired" + "403": + $ref: "#/components/responses/Forbidden" + "404": + $ref: "#/components/responses/NotFound" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalServerError" + "503": + $ref: "#/components/responses/ServiceUnavailable" + /insights/{ip_address}: + servers: + - url: https://geoip.maxmind.com/geoip/v2.1 + description: GeoIP web services + - url: https://sandbox.maxmind.com/geoip/v2.1 + description: >- + GeoIP sandbox. Use a license key from a Sandbox account. The sandbox + returns fixed test data for a small set of IP addresses. Other + addresses return `IP_ADDRESS_NOT_FOUND`. + get: + operationId: getInsights + summary: Look up insights data + description: >- + Returns GeoIP Insights data for the IP address. GeoLite does not offer + this service. + tags: + - GeoIP + parameters: + - $ref: "#/components/parameters/IPAddress" + - $ref: "#/components/parameters/Pretty" + responses: + "200": + description: The Insights record for the IP address. + content: + application/vnd.maxmind.com-insights+json: + schema: + $ref: "../components/geoip-records.yaml#/schemas/InsightsResponse" + examples: + insights: + $ref: "../examples/geoip/insights.yaml" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "402": + $ref: "#/components/responses/PaymentRequired" + "403": + $ref: "#/components/responses/Forbidden" + "404": + $ref: "#/components/responses/NotFound" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalServerError" + "503": + $ref: "#/components/responses/ServiceUnavailable" +components: + securitySchemes: + basicAuth: + type: http + scheme: basic + description: >- + The username is your MaxMind account ID. The password is your MaxMind + license key. The service accepts HTTPS requests only, with TLS 1.2 or + higher. + parameters: + IPAddress: + name: ip_address + in: path + required: true + description: >- + The IPv4 or IPv6 address to look up. Use the lowercase string `me` to + look up the IP address that sends the request. For IPv6, the canonical + form in RFC 5952 is recommended, but any valid form without a zone ID is + accepted. + schema: + type: string + examples: + ipv4: + value: 1.2.3.4 + ipv6: + value: 2001:db8::1:0:0:1 + me: + value: me + Pretty: + name: pretty + in: query + required: false + description: >- + If present, the response body is indented for reading, for example + `?pretty`. + schema: + type: string + responses: + BadRequest: + description: >- + The request is not valid. The `code` is one of: + + - `IP_ADDRESS_REQUIRED`: the request has an empty IP address. + + - `IP_ADDRESS_INVALID`: the IP address is not a valid IPv4 or IPv6 + address. + + - `IP_ADDRESS_RESERVED`: the IP address is in a reserved or private + range. + + - `SERVICE_INVALID`: the service is not available on this host. On + `geolite.info`, only Country and City are available. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: IP_ADDRESS_RESERVED + error: + You have supplied an IP address which belongs to a reserved or + private range. + Unauthorized: + description: >- + The credentials are missing or not valid. The `code` is one of: + + - `AUTHORIZATION_INVALID`: the account ID or license key is not valid. + + - `ACCOUNT_ID_REQUIRED`: the Basic credentials have no account ID. + + - `LICENSE_KEY_REQUIRED`: the Basic credentials have no license key. + headers: + WWW-Authenticate: + description: The authentication scheme, `Basic realm="geoip2"`. + schema: + type: string + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: AUTHORIZATION_INVALID + error: Your account ID or license key could not be authenticated. + PaymentRequired: + description: >- + The account has no funds for this service (`INSUFFICIENT_FUNDS`). For + GeoLite, `INSUFFICIENT_FUNDS` means the account used its daily query + limit. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: INSUFFICIENT_FUNDS + error: You do not have sufficient funds to use this service. + Forbidden: + description: >- + The account does not have permission to use this service + (`PERMISSION_REQUIRED`). A request that uses HTTP instead of HTTPS also + gets this status, but without a JSON body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: PERMISSION_REQUIRED + error: You do not have permission to use the service. + NotFound: + description: >- + The IP address is not in the database (`IP_ADDRESS_NOT_FOUND`). Some 404 + responses do not have a JSON body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: IP_ADDRESS_NOT_FOUND + error: The IP address '1.2.3.4' is not in our database. + TooManyRequests: + description: >- + MaxMind rate-limited the request, usually because of too many earlier + error responses. The response may have no body. + InternalServerError: + description: >- + The service had an unexpected error (`SERVER_ERROR`). The response may + have no body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: SERVER_ERROR + error: There was an error when processing this request. + ServiceUnavailable: + description: >- + The service has a temporary problem. Send the request again later. The + response does not have a JSON body. From aa6653beea7fba89a6697d249af13e1c4c9a6022 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Tue, 22 Sep 2026 18:34:54 +0000 Subject: [PATCH 02/31] Add minFraud web services spec Describe the minFraud Score, Insights, and Factors endpoints, the Report Transaction and Dispositions APIs, and the minFraud Alerts webhook in OpenAPI 3.1. The schemas, descriptions, and examples follow the developer documentation. The Insights and Factors ip_address object reuses the GeoIP record schemas instead of duplicating them. Co-Authored-By: Claude Opus 5.5 (1M context) --- CHANGELOG.md | 1 + README.md | 7 +- bundled/minfraud.yaml | 2466 +++++++++++++++++ components/minfraud-request.yaml | 734 +++++ components/minfraud-response.yaml | 712 +++++ .../minfraud/disposition-bad-request.yaml | 4 + examples/minfraud/disposition-updates.yaml | 34 + examples/minfraud/error.yaml | 4 + examples/minfraud/factors.yaml | 222 ++ examples/minfraud/insights.yaml | 205 ++ examples/minfraud/report-bad-request.yaml | 4 + examples/minfraud/request.yaml | 83 + examples/minfraud/score-bad-request.yaml | 4 + examples/minfraud/score.yaml | 18 + examples/minfraud/transaction-report.yaml | 5 + redocly.yaml | 3 + specs/minfraud.yaml | 601 ++++ 17 files changed, 5104 insertions(+), 3 deletions(-) create mode 100644 bundled/minfraud.yaml create mode 100644 components/minfraud-request.yaml create mode 100644 components/minfraud-response.yaml create mode 100644 examples/minfraud/disposition-bad-request.yaml create mode 100644 examples/minfraud/disposition-updates.yaml create mode 100644 examples/minfraud/error.yaml create mode 100644 examples/minfraud/factors.yaml create mode 100644 examples/minfraud/insights.yaml create mode 100644 examples/minfraud/report-bad-request.yaml create mode 100644 examples/minfraud/request.yaml create mode 100644 examples/minfraud/score-bad-request.yaml create mode 100644 examples/minfraud/score.yaml create mode 100644 examples/minfraud/transaction-report.yaml create mode 100644 specs/minfraud.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index ce89b1f..97c836b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,3 +3,4 @@ ## 0.1.0 - Add the GeoIP and GeoLite web services spec. +- Add the minFraud web services spec. diff --git a/README.md b/README.md index 59b0392..061534f 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,10 @@ This repository holds [OpenAPI 3.1](https://spec.openapis.org/oas/v3.1.2) descriptions of the MaxMind public web services. -| Product | Bundled spec | Documentation | -| ------------------------------ | ------------------------------------------ | ------------------------------------------------------------------- | -| GeoIP and GeoLite web services | [`bundled/geoip.yaml`](bundled/geoip.yaml) | [dev.maxmind.com](https://dev.maxmind.com/geoip/docs/web-services/) | +| Product | Bundled spec | Documentation | +| ------------------------------ | ------------------------------------------------ | ---------------------------------------------------------------------- | +| GeoIP and GeoLite web services | [`bundled/geoip.yaml`](bundled/geoip.yaml) | [dev.maxmind.com](https://dev.maxmind.com/geoip/docs/web-services/) | +| minFraud web services | [`bundled/minfraud.yaml`](bundled/minfraud.yaml) | [dev.maxmind.com](https://dev.maxmind.com/minfraud/api-documentation/) | Each file in `bundled/` is self-contained. Use it with API tools and code generators. The files in `specs/`, `components/`, and `examples/` are the diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml new file mode 100644 index 0000000..ca2feec --- /dev/null +++ b/bundled/minfraud.yaml @@ -0,0 +1,2466 @@ +openapi: 3.1.2 +info: + title: minFraud web services + version: 0.1.0 + summary: Fraud risk scoring for an online transaction. + description: |- + The minFraud web services score a transaction for fraud risk. Score, Insights, and Factors accept the same request body and return increasingly detailed risk data. Report a transaction's outcome to improve future scoring, and read back manual disposition changes made in the account portal. + + MaxMind can add fields, warning codes, and enum values to a response without a version change. Clients must ignore keys and values that they do not know. + contact: + name: MaxMind support + url: https://support.maxmind.com/ + license: + name: Apache 2.0 or MIT + identifier: Apache-2.0 OR MIT + termsOfService: https://www.maxmind.com/en/terms-of-use +servers: + - url: https://minfraud.maxmind.com + description: minFraud web services +security: + - basicAuth: [] +tags: + - name: Score, Insights, and Factors + description: Score a transaction for fraud risk. + - name: Report a Transaction + description: Report a transaction's outcome to improve future scoring. + - name: Dispositions + description: Read manual disposition and note changes made in the account portal. + - name: Alerts + description: Receive a webhook when MaxMind re-scores a low-risk transaction as high risk. +externalDocs: + description: minFraud API documentation + url: https://dev.maxmind.com/minfraud/api-documentation/ +paths: + /minfraud/v2.0/score: + servers: + - url: https://minfraud.maxmind.com + description: minFraud web services + - url: https://sandbox.maxmind.com + description: minFraud sandbox + post: + operationId: postScore + summary: Score a transaction + description: Returns the overall risk score and the risk for the IP address, but no other risk factor data. + tags: + - Score, Insights, and Factors + externalDocs: + url: https://dev.maxmind.com/minfraud/api-documentation/responses/ + requestBody: + $ref: '#/components/requestBodies/Transaction' + responses: + '200': + description: The Score response for the transaction. + content: + application/vnd.maxmind.com-minfraud-score+json: + schema: + $ref: '#/components/schemas/Score' + examples: + score: + $ref: '#/components/examples/score' + '400': + $ref: '#/components/responses/ScoreBadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '402': + $ref: '#/components/responses/PaymentRequired' + '403': + $ref: '#/components/responses/Forbidden' + '413': + $ref: '#/components/responses/ScorePayloadTooLarge' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalServerError' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /minfraud/v2.0/insights: + servers: + - url: https://minfraud.maxmind.com + description: minFraud web services + - url: https://sandbox.maxmind.com + description: minFraud sandbox + post: + operationId: postInsights + summary: Score a transaction with IP intelligence + description: Returns every field in the Score response, plus IP intelligence data such as anonymizer detection, and risk data about the device, email, billing address, shipping address, and credit card. + tags: + - Score, Insights, and Factors + externalDocs: + url: https://dev.maxmind.com/minfraud/api-documentation/responses/ + requestBody: + $ref: '#/components/requestBodies/Transaction' + responses: + '200': + description: The Insights response for the transaction. + content: + application/vnd.maxmind.com-minfraud-insights+json: + schema: + $ref: '#/components/schemas/Insights' + examples: + insights: + $ref: '#/components/examples/insights' + '400': + $ref: '#/components/responses/ScoreBadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '402': + $ref: '#/components/responses/PaymentRequired' + '403': + $ref: '#/components/responses/Forbidden' + '413': + $ref: '#/components/responses/ScorePayloadTooLarge' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalServerError' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /minfraud/v2.0/factors: + servers: + - url: https://minfraud.maxmind.com + description: minFraud web services + - url: https://sandbox.maxmind.com + description: minFraud sandbox + post: + operationId: postFactors + summary: Score a transaction with risk factors + description: Returns every field in the Insights response, plus the risk score reasons that explain the risk score. + tags: + - Score, Insights, and Factors + externalDocs: + url: https://dev.maxmind.com/minfraud/api-documentation/responses/ + requestBody: + $ref: '#/components/requestBodies/Transaction' + responses: + '200': + description: The Factors response for the transaction. + content: + application/vnd.maxmind.com-minfraud-factors+json: + schema: + $ref: '#/components/schemas/Factors' + examples: + factors: + $ref: '#/components/examples/factors' + '400': + $ref: '#/components/responses/ScoreBadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '402': + $ref: '#/components/responses/PaymentRequired' + '403': + $ref: '#/components/responses/Forbidden' + '413': + $ref: '#/components/responses/ScorePayloadTooLarge' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalServerError' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /minfraud/v2.0/transactions/report: + post: + operationId: reportTransaction + summary: Report a transaction's outcome + description: Reports a transaction as fraud, legitimate, or another outcome, so MaxMind can use it to improve future risk scores. Give at least one of `ip_address`, `maxmind_id`, `minfraud_id`, and `transaction_id` in the request body so MaxMind can match the report to the original transaction. + tags: + - Report a Transaction + externalDocs: + url: https://dev.maxmind.com/minfraud/report-a-transaction/ + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/TransactionReport' + examples: + transactionReport: + $ref: '#/components/examples/transaction-report' + responses: + '204': + description: MaxMind accepted the report. + '400': + $ref: '#/components/responses/ReportBadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '413': + $ref: '#/components/responses/ReportPayloadTooLarge' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalServerError' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /minfraud/disposition/v1.0/updates: + get: + operationId: listDispositionUpdates + summary: List disposition and note updates + description: Returns transactions whose disposition or note changed, through the account portal's manual review, after `updates_after`. Use this only if you set dispositions or notes from the account portal and need those changes in your own system. + tags: + - Dispositions + externalDocs: + url: https://dev.maxmind.com/minfraud/working-with-transaction-dispositions/ + parameters: + - name: updates_after + in: query + required: true + description: An exclusive lower bound, as an RFC 3339 timestamp. MaxMind returns only updates made after this time. URL-encode the value, for example send a `+` in the UTC offset as `%2B`. Pass the previous response's `last_update_timestamp` to page through results. + schema: + type: string + format: date-time + responses: + '200': + description: The transactions with a disposition or note update. + content: + application/vnd.maxmind.com-disposition-updates+json: + schema: + $ref: '#/components/schemas/DispositionUpdatesResponse' + examples: + dispositionUpdates: + $ref: '#/components/examples/disposition-updates' + '400': + $ref: '#/components/responses/DispositionBadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalServerError' + '503': + $ref: '#/components/responses/ServiceUnavailable' +webhooks: + minFraudAlert: + get: + operationId: minFraudAlert + security: [] + summary: Receive a minFraud Alert + description: |- + MaxMind monitors a transaction for 24 hours after it first scores 10 or below. If new information raises the re-calculated risk score to 75 or above, MaxMind sends this request to the webhook URL you configure in the account portal. Your endpoint must accept `GET` requests over HTTPS. + + MaxMind can add query parameters. Ignore parameters you do not know. Requests come from `34.27.174.58` or `2600:1900:4000:947::/64`. These source addresses can change. + tags: + - Alerts + externalDocs: + url: https://dev.maxmind.com/minfraud/alerts/ + parameters: + - name: User-Agent + in: header + required: false + description: The value is `MaxMind MinFraud Alert Robot`. + schema: + type: string + - name: X-MaxMind-Alert-HMAC-SHA256 + in: header + required: false + description: The hex-encoded HMAC-SHA256 signature of the raw query string, using the webhook secret you configure in the account portal. Present only when you configure a secret. + schema: + type: string + - name: city + in: query + required: false + description: The billing city from the original minFraud request. + schema: + type: string + maxLength: 255 + - name: country + in: query + required: false + description: The billing country from the original minFraud request. + schema: + type: string + maxLength: 2 + - name: date + in: query + required: false + description: The date of the original minFraud request, for example `Nov. 1, 2019`. + schema: + type: string + maxLength: 255 + - name: domain + in: query + required: false + description: The email domain from the original minFraud request. + schema: + type: string + maxLength: 255 + - name: i + in: query + required: false + description: The IP address from the original minFraud request. + schema: + type: string + anyOf: + - format: ipv4 + - format: ipv6 + - maxLength: 0 + - name: maxmindID + in: query + required: false + description: The minFraud Legacy `maxmindID` of the original request. + schema: + type: string + maxLength: 8 + - name: minfraud_id + in: query + required: false + description: The minFraud ID of the original request. + schema: + type: string + format: uuid + - name: new_risk_score + in: query + required: false + description: The risk score MaxMind recalculated with additional information. + schema: + type: number + minimum: 0.01 + maximum: 99 + - name: old_risk_score + in: query + required: false + description: The risk score as originally calculated. + schema: + type: number + minimum: 0.01 + maximum: 99 + - name: postal + in: query + required: false + description: The billing postal code from the original minFraud request. + schema: + type: string + maxLength: 255 + - name: reason + in: query + required: false + description: A human-readable explanation of why MaxMind sent the alert. + schema: + type: string + - name: reason_code + in: query + required: false + description: 'A machine-readable code for why MaxMind sent the alert. Known values: `CARDER_EMAIL`, `HIGH_RISK_DEVICE`, `HIGH_RISK_IP`, `HOSTING_PROVIDER`, `MANUAL_REVIEW`, `POSTAL_VELOCITY`. These values can change.' + schema: + type: string + - name: region + in: query + required: false + description: The billing region from the original minFraud request. + schema: + type: string + maxLength: 4 + - name: shop_id + in: query + required: false + description: The shop ID from the original minFraud request. Present only when the original request gave one. + schema: + type: string + maxLength: 255 + - name: txnID + in: query + required: false + description: The transaction ID from the original minFraud request. + schema: + type: string + maxLength: 255 + - name: updated_at + in: query + required: false + description: The date and time the new risk score was calculated, in RFC 3339 format, for example `2019-11-01T12:34:56Z`. + schema: + type: string + format: date-time + responses: + 2XX: + description: Return a 2xx status to acknowledge the alert. +components: + securitySchemes: + basicAuth: + type: http + scheme: basic + description: The username is your MaxMind account ID. The password is your MaxMind license key. The service accepts HTTPS requests only, with TLS 1.2 or higher. + requestBodies: + Transaction: + description: The request body must not exceed 20,000 bytes. + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Request' + examples: + request: + $ref: '#/components/examples/request' + responses: + ScoreBadRequest: + description: |- + The request is not valid. The `code` is one of: + - `JSON_INVALID`: the request body is not a JSON object. + - `REQUEST_INVALID`: the request body is valid JSON but has no valid input values. + - `REQUEST_TOO_BIG`: the request body is too large. + - `BAD_REQUEST`: there was a problem reading or decoding the request body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + examples: + error: + $ref: '#/components/examples/score-bad-request' + ReportBadRequest: + description: |- + The request is not valid. The `code` is one of: + - `JSON_INVALID`: the request body is not a valid JSON object. + - `PARAMETER_UNKNOWN`: the request has a key this endpoint does not use. + - `TAG_REQUIRED`: the request has no `tag`. + - `TAG_INVALID`: `tag` is not one of the accepted values. + - `TRANSACTION_ID_REQUIRED`: the request has none of `ip_address`, `maxmind_id`, `minfraud_id`, and `transaction_id`. + - `IP_ADDRESS_INVALID`: `ip_address` is not a valid IPv4 or IPv6 address. + - `IP_ADDRESS_RESERVED`: `ip_address` is in a reserved or private range. + - `MAXMIND_ID_INVALID`: `maxmind_id` is not a valid MaxMind ID. It must be 8 characters of digits and uppercase letters. + - `MINFRAUD_ID_INVALID`: `minfraud_id` is not a valid UUID. + - `NOTES_INVALID`: `notes` is over 1000 Unicode characters or contains a NUL character. + - Other `_INVALID` codes, for example `TRANSACTION_ID_INVALID`: the value of that field is not valid. `TRANSACTION_ID_INVALID` and `CHARGEBACK_CODE_INVALID` also cover a field that contains a NUL character. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + examples: + error: + $ref: '#/components/examples/report-bad-request' + DispositionBadRequest: + description: |- + The request is not valid. The `code` is one of: + - `UPDATES_AFTER_REQUIRED`: the request has no `updates_after` parameter, or its value is empty. + - `TIMESTAMP_INVALID`: `updates_after` is not a valid RFC 3339 timestamp. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + examples: + error: + $ref: '#/components/examples/disposition-bad-request' + Unauthorized: + description: |- + The credentials are missing or not valid. The `code` is one of: + - `AUTHORIZATION_INVALID`: the account ID or license key is not valid. + - `ACCOUNT_ID_REQUIRED`: the Basic credentials have no account ID. + - `LICENSE_KEY_REQUIRED`: the Basic credentials have no license key. + headers: + WWW-Authenticate: + description: The authentication scheme, for example `Basic realm="minfraud"`. + schema: + type: string + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + examples: + error: + value: + code: AUTHORIZATION_INVALID + error: Your account ID or license key could not be authenticated. + PaymentRequired: + description: The account has no funds for this service (`INSUFFICIENT_FUNDS`). + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + examples: + error: + $ref: '#/components/examples/error' + Forbidden: + description: The account does not have permission to use this service (`PERMISSION_REQUIRED`). A request that uses HTTP instead of HTTPS also gets this status, but without a JSON body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + examples: + error: + value: + code: PERMISSION_REQUIRED + error: You do not have permission to use the service. + ScorePayloadTooLarge: + description: The request body is larger than 20,000 bytes. The response does not have a JSON body. + ReportPayloadTooLarge: + description: The request body is too large. The response does not have a JSON body. + TooManyRequests: + description: MaxMind rate-limited the request, usually because of too many earlier error responses. The response may have no body. + InternalServerError: + description: The service had an unexpected error (`SERVER_ERROR`). + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + examples: + error: + value: + code: SERVER_ERROR + error: There was an error when processing this request. + ServiceUnavailable: + description: The service has a temporary problem. Send the request again later. The response does not have a JSON body. + schemas: + Account: + type: object + properties: + user_id: + type: string + maxLength: 255 + description: Your internal ID for the account. Use an ID that does not change, not a login name that can change. This is not your MaxMind account ID. + username_md5: + type: string + pattern: ^[0-9a-fA-F]{32}$ + description: An MD5 hash of the account username. + Address: + type: object + description: A billing or shipping address. + properties: + address: + type: string + maxLength: 255 + description: The first line of the street address. + address_2: + type: string + maxLength: 255 + description: The second line of the street address. + city: + type: string + maxLength: 255 + company: + type: string + maxLength: 255 + description: The company name for the address. + country: + type: string + pattern: ^[A-Z]{2}$ + description: The two-character ISO 3166-1 alpha-2 country code. + first_name: + type: string + maxLength: 255 + last_name: + type: string + maxLength: 255 + phone_country_code: + type: string + pattern: ^[0-9]{1,4}$ + description: The international calling code for the phone number. + phone_number: + type: string + maxLength: 255 + description: The phone number, without the country code. MaxMind strips punctuation characters. After that, the number must contain only digits. + postal: + type: string + maxLength: 255 + description: The postal code for the address. + region: + type: string + pattern: ^[0-9A-Z]{1,4}$ + description: The ISO 3166-2 subdivision code. + CreditCard: + type: object + properties: + avs_result: + type: string + pattern: ^[A-Za-z1-4]$ + description: The address verification system (AVS) check result, as your payment processor returns it. MaxMind supports the standard AVS codes. + bank_name: + type: string + maxLength: 255 + description: The name of the bank that issued the credit card. + bank_phone_country_code: + type: string + pattern: ^[0-9]{1,4}$ + description: The international calling code for the bank's phone number. + bank_phone_number: + type: string + maxLength: 255 + description: The bank's phone number, without the country code. MaxMind strips punctuation characters. After that, the number must contain only digits. + country: + type: string + pattern: ^[A-Z]{2}$ + description: The two-character ISO 3166-1 country code of the card issuer's location. You can send this instead of `issuer_id_number` if you do not want to send partial account numbers, or if your payment processor does not provide them. + cvv_result: + type: string + pattern: ^[A-Za-z0-9]$ + description: The card verification value (CVV) check result, as your payment processor returns it. + issuer_id_number: + type: string + pattern: ^([0-9]{6}|[0-9]{8})$ + description: The first 6 or 8 digits of the credit card number. If you do not know whether the number is 6 or 8 digits long, send 6 digits. + last_digits: + type: string + pattern: ^([0-9]{2}|[0-9]{4})$ + description: The last 2 or 4 digits of the credit card number. Send the last 4 digits in most cases. If `issuer_id_number` has 8 digits and the card brand is not Discover, JCB, Mastercard, UnionPay, or Visa, send the last 2 digits. + token: + type: string + maxLength: 255 + pattern: ^[!-~]+$ + not: + pattern: ^[0-9]{1,19}$ + description: A token that uniquely identifies the card, for example one your payment processor gives you. The token must consist of non-space printable ASCII characters. If the token is all digits, it must be more than 19 characters long. The token must not be a primary account number (PAN) or a simple transformation of one. If a valid token looks like a PAN but is not one, you can prefix it with a fixed string, for example `token-`. + was_3d_secure_successful: + type: boolean + description: Whether the 3-D Secure check for the transaction was successful. Omit this field if 3-D Secure verification was not used, was unavailable, or had another outcome besides success or failure. + CustomInputs: + type: object + description: 'Values for the custom inputs that you configure for your account. Configure each key first, from Custom Inputs in the account portal. Each key must match a key configured for your account, and the value must match the type configured for that key: a boolean, a number from -9999999999999 to 9999999999999, a string of up to 255 characters, or a phone number string of up to 255 characters. MaxMind strips spaces and punctuation from a phone number, and the rest must be digits. A key that your account does not have configured produces an `INPUT_UNKNOWN` warning. Do not send a full credit card number as a value. MaxMind rejects it and returns a warning.' + additionalProperties: + oneOf: + - type: boolean + - type: number + minimum: -9999999999999 + maximum: 9999999999999 + - type: string + maxLength: 255 + Device: + type: object + properties: + accept_language: + type: string + maxLength: 255 + description: The HTTP `Accept-Language` header of the device. + ip_address: + type: string + maxLength: 255 + description: The IPv4 or IPv6 address of the device, in presentation format (dotted-quad notation or IPv6 colon notation). A private or reserved address produces an `IP_ADDRESS_RESERVED` warning. + session_age: + type: number + minimum: 0 + maximum: 9999999999999 + description: The number of seconds between the creation of the user's session and the transaction. This is not the length of the current visit. It is the time since the start of the first visit. + session_id: + type: string + maxLength: 255 + description: An ID that identifies a visitor's session on the site. + tracking_token: + type: string + description: The token that the Device Tracking Add-On client-side code returns for explicit device linking. + user_agent: + type: string + maxLength: 512 + description: The HTTP `User-Agent` header of the browser used. + Email: + type: object + properties: + address: + type: string + maxLength: 255 + description: The email address, or the MD5 hash of the normalized email address. Normalize the address before you hash it. See https://dev.maxmind.com/minfraud/normalizing-email-addresses-for-minfraud. A plaintext address must be a valid email address. MaxMind lowercases it, converts an internationalized domain to ASCII, and fixes a few common typos, such as a misspelled `gmail.com`. + domain: + type: string + maxLength: 255 + description: The domain of the email address. Do not include the `@`. You do not need to send this field unless you send the email address as an MD5 hash. MaxMind lowercases the domain, converts an internationalized domain to ASCII, and fixes a few common typos. + Event: + type: object + properties: + party: + type: string + enum: + - agent + - customer + description: The party that submits the transaction. + shop_id: + type: string + maxLength: 255 + description: Your internal ID for the shop, affiliate, or merchant the order comes from. Required for a reseller, payment provider, gateway, or affiliate network. If you are testing the minFraud service, prefix your shop ID with `test`, or set it to `test`. + time: + type: string + format: date-time + description: |- + The time the event occurred, in RFC 3339 format. If you omit this field, MaxMind uses the time it receives the request. Do not send this field for a live transaction. Use it only for a stored transaction that you score later. + + The time must be within the past year. For an older time, MaxMind uses the current time to score the transaction and returns a warning. + transaction_id: + type: string + maxLength: 255 + description: Your internal ID for the transaction. + type: + type: string + enum: + - account_creation + - account_login + - credit_application + - email_change + - fund_transfer + - password_reset + - payout_change + - purchase + - recurring_purchase + - referral + - sim_swap + - survey + description: |- + The type of event being scored. + + - `account_creation`: the transactor is creating an account. + - `account_login`: the transactor is logging in to an account. + - `credit_application`: the transactor is applying for credit. + - `email_change`: the transactor is changing the email address on an account. + - `fund_transfer`: the transactor is transferring funds between accounts. + - `password_reset`: the transactor is resetting a password. + - `payout_change`: the transactor is changing how you pay them. Use this for any case where you pay your users and they change how you pay them, such as a referral or survey payout. + - `purchase`: the transactor is making a purchase. + - `recurring_purchase`: the transactor is setting up a recurring purchase or subscription. + - `referral`: the transactor is sending you referral traffic, for example by referring someone to your site with an ad. + - `sim_swap`: for a mobile network operator. A new SIM card or eSIM is being issued for a customer's existing phone number. + - `survey`: the transactor is starting or completing a survey. + Order: + type: object + properties: + affiliate_id: + type: string + maxLength: 255 + description: Your internal ID for the affiliate that referred the order. + amount: + type: number + minimum: 0 + maximum: 9999999999999 + description: The total order amount before taxes and discounts, in the currency given in `currency`. + currency: + type: string + pattern: ^[A-Z]{3}$ + description: The ISO 4217 currency code for the order amount. + discount_code: + type: string + maxLength: 255 + description: The discount code applied to the order. Separate multiple discount codes with a comma. + has_gift_message: + type: boolean + description: Whether the order included a gift message. + is_gift: + type: boolean + description: Whether the order was marked as a gift. + referrer_uri: + type: string + maxLength: 1024 + format: uri + description: The URI of the site that referred the customer to your site. Must be an absolute URI with a scheme, such as `https://`. + subaffiliate_id: + type: string + maxLength: 255 + description: Your internal ID for the subaffiliate that referred the order. + Payment: + type: object + properties: + decline_code: + type: string + maxLength: 255 + description: The decline code the payment processor returned. Omit this field if the transaction was not declined. + method: + type: string + enum: + - bank_debit + - bank_redirect + - bank_transfer + - buy_now_pay_later + - card + - crypto + - digital_wallet + - gift_card + - real_time_payment + - rewards + description: |- + The payment method. + + - `bank_debit`: a direct debit of the customer's bank account. + - `bank_redirect`: the customer authorizes payment after authenticating with their bank. + - `bank_transfer`: the customer pushes funds directly from their bank account. + - `buy_now_pay_later`: payment through a buy now, pay later provider, such as Affirm, Afterpay, or Klarna. + - `card`: payment by a credit, debit, or charge card. + - `crypto`: payment with a cryptocurrency. + - `digital_wallet`: payment from a digital wallet linked to a card or bank account, such as Apple Pay, Google Pay, or PayPal. + - `gift_card`: payment with a merchant-sponsored gift card. + - `real_time_payment`: the customer pushes funds directly from their bank account or another funding source, using an intermediary such as a phone number to authenticate, for example Pix, PayNow, or Swish. + - `rewards`: payment with rewards or loyalty program incentives. + processor: + type: string + description: The payment processor used for the transaction. + enum: + - adyen + - affirm + - afterpay + - altapay + - amazon_payments + - american_express_payment_gateway + - apple_pay + - aps_payments + - authorizenet + - balanced + - banquest + - beanstream + - bluepay + - bluesnap + - boacompra + - boku + - bpoint + - braintree + - cardknox + - cardpay + - cashfree + - ccavenue + - ccnow + - cetelem + - chase_paymentech + - checkout_com + - cielo + - collector + - commdoo + - compropago + - concept_payments + - conekta + - coregateway + - creditguard + - credorax + - cryptomus + - ct_payments + - cuentadigital + - curopayments + - cybersource + - dalenys + - dalpay + - datacap + - datacash + - dibs + - digital_river + - dlocal + - dotpay + - ebs + - ecomm365 + - ecommpay + - elavon + - emerchantpay + - epay + - epayco + - eprocessing_network + - epx + - eway + - exact + - fat_zebra + - first_atlantic_commerce + - first_data + - fiserv + - g2a_pay + - global_payments + - gocardless + - google_pay + - heartland + - hipay + - ingenico + - interac + - internetsecure + - intuit_quickbooks_payments + - iugu + - klarna + - komoju + - lemon_way + - mastercard_payment_gateway + - mercadopago + - mercanet + - merchant_esolutions + - mirjeh + - mollie + - moneris_solutions + - neopay + - neosurf + - nmi + - oceanpayment + - oney + - onpay + - openbucks + - openpaymx + - optimal_payments + - orangepay + - other + - pacnet_services + - payconex + - payeezy + - payfast + - paygate + - paylike + - payment_express + - paymentwall + - payone + - paypal + - payplus + - paysafecard + - paysera + - paystation + - paytm + - paytrace + - paytrail + - payture + - payu + - payulatam + - payvision + - payway + - payza + - pinpayments + - placetopay + - posconnect + - princeton_payment_solutions + - psigate + - pxp_financial + - qiwi + - quickpay + - raberil + - razorpay + - rede + - redpagos + - rewardspay + - safecharge + - sagepay + - securepay + - securetrading + - shopify_payments + - simplify_commerce + - skrill + - smartcoin + - smartdebit + - solidtrust_pay + - sps_decidir + - stripe + - summit_payments + - synapsefi + - systempay + - telerecargas + - towah + - transact_pro + - trustly + - trustpay + - tsys + - usa_epay + - vantiv + - verepay + - vericheck + - vindicia + - virtual_card_services + - vme + - vpos + - windcave + - wirecard + - worldpay + - yaadpay + was_authorized: + type: boolean + description: Whether the payment was authorized. Omit this field if the transaction has not yet been approved or denied. + Shipping: + description: A shipping address, with the delivery speed for the order. + allOf: + - $ref: '#/components/schemas/Address' + - type: object + properties: + delivery_speed: + type: string + enum: + - same_day + - overnight + - expedited + - standard + description: The shipping speed selected for the order. + ShoppingCartItem: + type: object + description: An item purchased in the order. You can hash `category` and `item_id` with a cryptographic hash function and a fixed salt to protect customer privacy. Do not use a random salt. A random salt produces a different hash each time for the same value, which defeats fraud detection. + properties: + category: + type: string + maxLength: 255 + description: The category of the item. This can be a hashed value. + item_id: + type: string + maxLength: 255 + description: Your internal ID for the item. This can be a hashed value. + price: + type: number + minimum: 0 + maximum: 9999999999999 + description: The per-unit price of the item. This should use the same currency as the order's `currency`. + quantity: + type: integer + minimum: 0 + maximum: 9999999999999 + description: The quantity of the item purchased. + Request: + type: object + description: |- + The minFraud request body. Score, Insights, and Factors accept the same request body. Every object is optional. Add more fields to improve accuracy. + + MaxMind can add fields to the request body without a version change. A field that MaxMind does not recognize produces an `INPUT_UNKNOWN` warning. + + A string field allows up to 255 valid Unicode characters unless its schema states a shorter limit. Null and newline characters are not allowed. MaxMind accepts a number sent as a string and a string sent as a number, and converts it to the type the field requires. + + A value that does not meet a field's constraints, such as its pattern, enum, or length, produces an `INPUT_INVALID` warning in the response. The request still succeeds. + minProperties: 1 + properties: + account: + $ref: '#/components/schemas/Account' + description: Information about the account involved in the event. + billing: + $ref: '#/components/schemas/Address' + description: The billing address for the order. + credit_card: + $ref: '#/components/schemas/CreditCard' + description: Information about the credit card used. + custom_inputs: + $ref: '#/components/schemas/CustomInputs' + device: + $ref: '#/components/schemas/Device' + description: Information about the device used in the transaction. + email: + $ref: '#/components/schemas/Email' + description: Information about the email used in the transaction. + event: + $ref: '#/components/schemas/Event' + description: General information about the event being scored. + order: + $ref: '#/components/schemas/Order' + description: Information about the order. + payment: + $ref: '#/components/schemas/Payment' + description: Information about the payment method used. + shipping: + $ref: '#/components/schemas/Shipping' + description: The shipping address for the order. + shopping_cart: + type: array + description: The items purchased in the order. + items: + $ref: '#/components/schemas/ShoppingCartItem' + Disposition: + type: object + description: How a custom rule disposed of the request. Not present when your account has no custom rules. + properties: + action: + type: string + description: 'How MaxMind handled the request. Known values: `accept`, `reject`, `manual_review`, `test`. MaxMind may add values. `accept` is the default when no custom rule matches. Use `test` to test custom rules.' + reason: + type: string + description: 'Why `action` has its value. Known values: `default`, `custom_rule`. MaxMind may add values.' + rule_label: + type: string + description: The label of the custom rule that was triggered. Not present when you have no custom rules, the triggered rule has no label, or no rule was triggered. + Warning: + type: object + description: |- + A warning about an issue with the request. The `code` values below are the current set. MaxMind can add more. + + - `BILLING_CITY_NOT_FOUND`: the billing city is not in the MaxMind database. + - `BILLING_COUNTRY_MISSING`: billing address fields are present but `country` is not. + - `BILLING_COUNTRY_NOT_FOUND`: the billing country is not in the MaxMind database. + - `BILLING_POSTAL_NOT_FOUND`: the billing postal code is not in the MaxMind database. + - `BILLING_REGION_NOT_FOUND`: the billing region is not in the MaxMind database. + - `EMAIL_ADDRESS_UNUSABLE`: the email address looks incorrect, so MaxMind left it out of scoring. + - `INPUT_INVALID`: a value does not meet the field's constraints. + - `INPUT_UNKNOWN`: the request has a key MaxMind does not recognize. + - `IP_ADDRESS_INVALID`: the IP address is not a valid IPv4 or IPv6 address. + - `IP_ADDRESS_NOT_FOUND`: MaxMind could not geolocate the IP address. + - `IP_ADDRESS_RESERVED`: the IP address is in a reserved network. + - `SHIPPING_CITY_NOT_FOUND`: the shipping city is not in the MaxMind database. + - `SHIPPING_COUNTRY_MISSING`: shipping address fields are present but `country` is not. + - `SHIPPING_COUNTRY_NOT_FOUND`: the shipping country is not in the MaxMind database. + - `SHIPPING_POSTAL_NOT_FOUND`: the shipping postal code is not in the MaxMind database. + - `SHIPPING_REGION_NOT_FOUND`: the shipping region is not in the MaxMind database. + - `TRACKING_TOKEN_INVALID`: the tracking token is malformed. + - `TRACKING_TOKEN_NOT_FOUND`: MaxMind does not recognize the tracking token. + + The address warnings can reduce the accuracy of distance calculations. + properties: + code: + type: string + maxLength: 255 + input_pointer: + type: string + description: A JSON Pointer to the request field the warning is about, for example `/billing/city` or `/shopping_cart/1/price`. + warning: + type: string + description: A human-readable explanation of the warning. The text can change at any time. + ScoreBase: + type: object + description: The fields common to the minFraud Score, Insights, and Factors responses, apart from `ip_address`. Score, Insights, and Factors each have a different shape for `ip_address`. + properties: + disposition: + $ref: '#/components/schemas/Disposition' + description: How a custom rule disposed of the request. + funds_remaining: + type: number + minimum: 0 + description: The approximate US dollar value of the funds left on your account. + id: + type: string + format: uuid + description: The minFraud ID for this response. Use it to find the request in your minFraud logs, or when you contact MaxMind support. + queries_remaining: + type: integer + minimum: 0 + description: The approximate number of queries left for this service before your account runs out of funds. + risk_score: + type: number + minimum: 0.01 + maximum: 99 + description: The overall risk score, from 0.01 to 99. A higher score means a higher risk of fraud. For example, a score of 20 means a 20% chance that the transaction is fraudulent. MaxMind never returns 0 or 100, since every transaction carries some possibility of fraud. + warnings: + type: array + description: Issues with the request, such as an invalid or unknown input. + items: + $ref: '#/components/schemas/Warning' + required: + - id + - risk_score + - funds_remaining + - queries_remaining + ScoreIPAddress: + type: object + description: The risk for the IP address, as returned by minFraud Score. + properties: + risk: + type: number + minimum: 0.01 + maximum: 99 + description: The risk for the IP address, from 0.01 to 99. A higher value means higher risk. + Score: + description: The minFraud Score response. + allOf: + - $ref: '#/components/schemas/ScoreBase' + - type: object + properties: + ip_address: + $ref: '#/components/schemas/ScoreIPAddress' + description: The risk associated with the IP address. + Error: + type: object + description: Not all error responses have a JSON body. Check the `Content-Type` header before you decode the body as JSON. + required: + - code + - error + properties: + code: + type: string + description: A static error code for machine use. The meaning of a code never changes, but MaxMind can add or remove codes. + examples: + - IP_ADDRESS_INVALID + error: + type: string + description: A human-readable description of the error. The text can change at any time. + examples: + - The value '1.2.3' is not a valid IP address. + AddressInsights: + type: object + description: minFraud risk data about a billing address. + properties: + distance_to_ip_location: + type: integer + description: The distance, in kilometers, from the address to the IP address's location. When MaxMind cannot locate the address or the IP address more precisely, it uses country or subdivision coordinates, which can make this distance inaccurate. + is_in_ip_country: + type: boolean + description: True if the address is in the IP address's country. Present only when MaxMind can geolocate the IP address and the address was given. + is_postal_in_city: + type: boolean + description: True if the postal code is in the city for the address. Present only when the postal code, city, and country were all given. MaxMind matches the postal code against the GeoNames preferred place name for a US ZIP code. An alternative place name for a US ZIP code might not produce a match. + latitude: + type: number + description: The approximate WGS 84 latitude for the address. The coordinates are not precise. Do not use them to identify a street address or household. + longitude: + type: number + description: The approximate WGS 84 longitude for the address. The coordinates are not precise. Do not use them to identify a street address or household. + Phone: + type: object + description: minFraud risk data about a billing or shipping phone number. + properties: + country: + type: string + description: The two-character ISO 3166-1 country code for the phone number. + is_voip: + type: boolean + description: True if the phone number is a VoIP number allocated by a regulator. Present only for a valid phone number that MaxMind has data for. + matches_postal: + type: boolean + description: True if the phone number's prefix is commonly associated with the postal code. Present only for a US number when MaxMind has the number's prefix, and the postal code and country were also given. + network_operator: + type: string + description: The original network operator associated with the phone number. This does not reflect a number ported to another operator, and it does not identify a mobile virtual network operator. + number_type: + type: string + description: 'The phone number''s type. Known values: `fixed`, `mobile`. MaxMind may add values.' + CreditCardIssuer: + type: object + description: minFraud risk data about a credit card's issuing bank. + properties: + matches_provided_name: + type: boolean + description: True if `name` matches the issuer name given in the request. Present only when the request gives both a name and an issuer ID number, and MaxMind has a name for that issuer ID number. + matches_provided_phone_number: + type: boolean + description: True if `phone_number` matches the issuer phone number given in the request. Present only when the request gives both a phone number and an issuer ID number, and MaxMind has a phone number for that issuer ID number. + name: + type: string + maxLength: 255 + description: The name of the issuing bank. + phone_number: + type: string + maxLength: 255 + description: The phone number of the issuing bank. This number can be out of date. + ResponseCreditCard: + type: object + description: minFraud risk data about the credit card. Present only when the request includes an issuer ID number. + properties: + brand: + type: string + maxLength: 255 + description: The card brand, for example "Visa" or "Discover". + country: + type: string + pattern: ^[A-Z]{2}$ + description: The two-character ISO 3166-1 country code for the majority of customers using this card, by billing address. If customers are spread across countries, this is the country of the issuing bank instead. + is_business: + type: boolean + description: True if the issuer ID number is for a business card. Present only when a valid issuer ID number was given. + is_issued_in_billing_address_country: + type: boolean + description: True if the billing address country matches the country of the majority of customers using this issuer ID number. Present only when both countries are known. When the customers for this issuer ID number are spread across many countries, MaxMind matches against the country of the issuing bank instead. + is_prepaid: + type: boolean + description: True if the issuer ID number is for a prepaid card. Present only when a valid issuer ID number was given. + is_virtual: + type: boolean + description: True if the issuer ID number is for a virtual card. Present only when a valid issuer ID number was given. + issuer: + $ref: '#/components/schemas/CreditCardIssuer' + description: Data about the bank that issued the card. + type: + type: string + description: 'The card''s type. Known values: `charge`, `credit`, `debit`. MaxMind may add values.' + ResponseDevice: + type: object + description: Data about the device MaxMind associates with the IP address in the request. + properties: + confidence: + type: number + minimum: 0.01 + maximum: 99 + description: MaxMind's confidence that `id` refers to a unique device rather than a cluster of similar devices, from 0.01 to 99. A higher value means higher confidence. + id: + type: string + format: uuid + description: MaxMind's ID for the device. Present only when the Device Tracking Add-On is in use. + last_seen: + type: string + format: date-time + description: The date and time MaxMind last saw the device, in RFC 3339 format. + local_time: + type: string + format: date-time + description: The local date and time of the transaction in the device's time zone, using the device's UTC offset, in RFC 3339 format. + EmailDomainVisit: + type: object + description: Data from an automated visit to the email domain. Not present for a high-volume domain, such as one for a large email provider or business, and can be delayed for a newly-seen domain. + properties: + has_redirect: + type: boolean + description: True if the domain redirects to another URL. Absent, not `false`, when the domain does not redirect. When true, `status` describes the domain the visit redirected to. + last_visited_on: + type: string + format: date + description: The date of the automated visit. + status: + type: string + description: 'The status of the domain, or of the domain a redirect led to, as of the automated visit. Known values: `live`, `dns_error`, `network_error`, `http_error`, `parked`, `pre_development`. MaxMind may add values.' + EmailDomain: + type: object + description: minFraud risk data about an email domain. + properties: + classification: + type: string + description: 'A classification of the domain. Known values: `business`, `education`, `government`, `isp_email`. MaxMind may add values.' + first_seen: + type: string + format: date + description: The date MaxMind first saw the email domain. The earliest possible date is 2019-01-01. + risk: + type: number + minimum: 0.01 + maximum: 99 + description: The risk associated with the domain, from 0.01 to 99. A higher value means higher risk. + visit: + $ref: '#/components/schemas/EmailDomainVisit' + description: Data from an automated visit to the email domain. + volume: + type: number + minimum: 0.001 + maximum: 1000000 + description: The activity MaxMind sees on this email domain across the minFraud network, in sightings per million requests. The value is rounded to 2 significant figures. + ResponseEmail: + type: object + description: Email intelligence data. + properties: + domain: + $ref: '#/components/schemas/EmailDomain' + description: Data about the email domain. + first_seen: + type: string + format: date + description: The date MaxMind first saw the email address. The earliest possible date is 2008-01-01. + is_disposable: + type: boolean + description: True if MaxMind believes the email address is from a disposable email provider. Present only when the request gives a valid email address or domain. + is_free: + type: boolean + description: True if MaxMind believes the email domain is for a free provider, such as Gmail or Yahoo! Mail. Present only when the request gives a valid email address or domain. + is_high_risk: + type: boolean + description: True if MaxMind believes the email address is likely to be used for fraud. This is also factored into `risk_score`. Present only when the request gives a valid email address or hash. + AnonymizerResidential: + type: object + description: Data about the residential proxy network associated with an IP address. Only in the Insights response. + properties: + confidence: + type: integer + minimum: 1 + maximum: 99 + description: MaxMind's confidence that the network is an actively used residential proxy, from 1 to 99. + network_last_seen: + type: string + format: date + description: The last date MaxMind saw the network in its residential proxy analysis. + provider_name: + type: string + description: The name of the residential proxy provider, for example `oxylabs`. MaxMind identifies only a subset of residential proxy providers. + Anonymizer: + type: object + description: Whether an IP address is part of an anonymizing service or network. Only in the Insights response. + properties: + confidence: + type: integer + minimum: 1 + maximum: 99 + description: MaxMind's confidence that the network is an actively used VPN, from 1 to 99. MaxMind currently returns only 30 or 99, and will add more values over time. + is_anonymous: + type: boolean + description: True if the IP address belongs to any anonymous network. + is_anonymous_vpn: + type: boolean + description: True if the IP address belongs to an anonymous VPN provider. Some VPN providers register their ranges under other names, so MaxMind may flag them with `is_hosting_provider` instead. + is_hosting_provider: + type: boolean + description: True if the IP address belongs to a hosting provider. + is_public_proxy: + type: boolean + description: True if the IP address belongs to a public proxy. + is_residential_proxy: + type: boolean + description: True if the IP address is on a suspected anonymizing network and belongs to a residential ISP. This excludes peer-to-peer proxy IP addresses. + is_tor_exit_node: + type: boolean + description: True if the IP address is a Tor exit node. + network_last_seen: + type: string + format: date + description: The last date MaxMind saw the network in its anonymizer analysis. + provider_name: + type: string + description: The name of the VPN provider, for example `nordvpn`. MaxMind identifies only a subset of VPN providers. + residential: + $ref: '#/components/schemas/AnonymizerResidential' + Names: + type: object + description: 'A map from a locale code to the localized name for the entity. Known locale codes: de, en, es, fr, ja, pt-BR, ru, zh-CN. If the entity has name data, en is present. No other locale is guaranteed. Names can change between releases. Do not use them as keys. Use `geoname_id`, `iso_code`, or `code`.' + additionalProperties: + type: string + City: + type: object + description: The city associated with an IP address. + properties: + geoname_id: + type: integer + minimum: 0 + description: The GeoNames ID for the city. + names: + $ref: '#/components/schemas/Names' + CityWithConfidence: + description: A city associated with an IP address, with MaxMind's confidence in the result. Only the Insights response's `city` object includes `confidence`. + allOf: + - $ref: '#/components/schemas/City' + - type: object + properties: + confidence: + type: integer + minimum: 0 + maximum: 100 + description: MaxMind's confidence that the city is correct, from 0 to 100. + Continent: + type: object + description: The continent associated with an IP address. + properties: + code: + type: string + description: The two-character code for the continent. + enum: + - AF + - AN + - AS + - EU + - NA + - OC + - SA + geoname_id: + type: integer + minimum: 0 + description: The GeoNames ID for the continent. + names: + $ref: '#/components/schemas/Names' + Country: + type: object + description: A country associated with an IP address. + properties: + geoname_id: + type: integer + minimum: 0 + description: The GeoNames ID for the country. + iso_code: + type: string + description: The two-character ISO 3166-1 country code. + is_in_european_union: + type: boolean + description: True if the country is a member state of the European Union. + names: + $ref: '#/components/schemas/Names' + CountryWithConfidence: + description: A country associated with an IP address, with MaxMind's confidence in the result. Only the Insights response's `country` object includes `confidence`. + allOf: + - $ref: '#/components/schemas/Country' + - type: object + properties: + confidence: + type: integer + minimum: 0 + maximum: 100 + description: MaxMind's confidence that the country is correct, from 0 to 100. + InsightsIPAddressCountry: + description: A country associated with an IP address, with MaxMind's confidence in the result and whether MaxMind considers the country high-risk. + allOf: + - $ref: '#/components/schemas/CountryWithConfidence' + - type: object + properties: + is_high_risk: + type: boolean + deprecated: true + description: Deprecated. True if MaxMind considers the IP address's country to be high-risk. + Location: + type: object + description: Location details for an IP address. + properties: + accuracy_radius: + type: integer + minimum: 0 + description: The approximate accuracy radius, in kilometers, around the latitude and longitude. MaxMind has 67% confidence that the true location falls within this radius of the coordinates. + latitude: + type: number + minimum: -90 + maximum: 90 + description: The approximate WGS 84 latitude for the location. The coordinates are not precise. Do not use them to identify a street address or household. When you show the coordinates, also show `accuracy_radius`. + longitude: + type: number + minimum: -180 + maximum: 180 + description: The approximate WGS 84 longitude for the location. The coordinates are not precise. Do not use them to identify a street address or household. When you show the coordinates, also show `accuracy_radius`. + metro_code: + type: integer + minimum: 0 + deprecated: true + description: Deprecated. A code that Google previously used to target ads. MaxMind no longer maintains this code. + time_zone: + type: string + description: The IANA time zone for the location, for example `America/New_York`. + InsightsLocation: + description: Location details for an IP address, including the fields the Insights response adds beyond City Plus. + allOf: + - $ref: '#/components/schemas/Location' + - type: object + properties: + average_income: + type: integer + minimum: 0 + description: The average annual income, in US dollars, for the IP address's location. Only available for IP addresses in the US. + population_density: + type: integer + minimum: 0 + description: The estimated number of people per square kilometer at the IP address's location. Only available for IP addresses in the US. + InsightsIPAddressLocation: + description: Location details for an IP address, including the local time at that location. + allOf: + - $ref: '#/components/schemas/InsightsLocation' + - type: object + properties: + local_time: + type: string + format: date-time + description: The date and time of the transaction in the time zone associated with the IP address, in RFC 3339 format. + Postal: + type: object + description: The postal code associated with an IP address. + properties: + code: + type: string + description: 'A postal code close to the IP address''s location. For some countries, MaxMind returns only part of the code, with this many characters: Brazil 5, Canada 3, Ireland 3, Japan 7, Netherlands 4, Portugal 7, Singapore 2, United Kingdom 2-4, United States 5. For Japan, the last digit defaults to 1. For Portugal, the last 3 digits often default to `-001`.' + PostalWithConfidence: + description: A postal code associated with an IP address, with MaxMind's confidence in the result. Only the Insights response's `postal` object includes `confidence`. + allOf: + - $ref: '#/components/schemas/Postal' + - type: object + properties: + confidence: + type: integer + minimum: 0 + maximum: 100 + description: MaxMind's confidence that the postal code is correct, from 0 to 100. + RepresentedCountry: + description: The country represented by users of an IP address, for example the country represented by an overseas military base. + allOf: + - $ref: '#/components/schemas/Country' + - type: object + properties: + type: + type: string + description: 'The type of represented country. Known value: military. MaxMind may add other values.' + IPRiskReason: + type: object + description: |- + A reason why an IP address received its risk. The `code` values below are the current set. MaxMind can add more. + + - `ANONYMOUS_IP`: the IP address belongs to an anonymous network. + - `BILLING_POSTAL_VELOCITY`: many billing postal codes have been seen on this IP address. + - `EMAIL_VELOCITY`: many email addresses have been seen on this IP address. + - `HIGH_RISK_DEVICE`: a high-risk device was seen on this IP address. + - `HIGH_RISK_EMAIL`: a high-risk email address was seen on this IP address in your past transactions. + - `ISSUER_ID_NUMBER_VELOCITY`: many issuer ID numbers have been seen on this IP address. + - `MINFRAUD_NETWORK_ACTIVITY`: MaxMind has seen suspicious activity on this IP address across minFraud customers. + properties: + code: + type: string + maxLength: 255 + reason: + type: string + description: A human-readable explanation of the reason. The text can change at any time. + Subdivision: + type: object + description: A subdivision of the country associated with an IP address. + properties: + geoname_id: + type: integer + minimum: 0 + description: The GeoNames ID for the subdivision. + iso_code: + type: string + description: Up to three characters from the ISO 3166-2 code for the subdivision. + names: + $ref: '#/components/schemas/Names' + SubdivisionWithConfidence: + description: A subdivision of the country associated with an IP address, with MaxMind's confidence in the result. Only the Insights response's `subdivisions` entries include `confidence`. + allOf: + - $ref: '#/components/schemas/Subdivision' + - type: object + properties: + confidence: + type: integer + minimum: 0 + maximum: 100 + description: MaxMind's confidence that the subdivision is correct, from 0 to 100. + CountryTraits: + type: object + description: General traits for an IP address, as returned by the Country response. + required: + - ip_address + - network + properties: + ip_address: + type: string + description: The IPv4 or IPv6 address that was looked up. + is_anycast: + type: boolean + description: True if the IP address belongs to an anycast network. + network: + type: string + description: The largest network, in CIDR notation, that shares the same data as this record, apart from `ip_address` itself. + CityTraits: + description: General traits for an IP address, including the fields the City Plus response adds beyond Country. + allOf: + - $ref: '#/components/schemas/CountryTraits' + - type: object + properties: + autonomous_system_number: + type: integer + minimum: 0 + description: The autonomous system number for the IP address. + autonomous_system_organization: + type: string + description: The organization for the autonomous system number. + connection_type: + type: string + description: 'The connection type for the IP address. Known values: `Cable/DSL`, `Cellular`, `Corporate`, `Satellite`. MaxMind may add values. GeoLite City does not include this field.' + domain: + type: string + description: The second-level domain for the IP address, for example `example.com`. This is not a subdomain such as `foo.example.com`. GeoLite City does not include this field. + isp: + type: string + description: The ISP for the IP address. GeoLite City does not include this field. + mobile_country_code: + type: string + description: The mobile country code (MCC) for the IP address and ISP. GeoLite City does not include this field. + mobile_network_code: + type: string + description: The mobile network code (MNC) for the IP address and ISP. GeoLite City does not include this field. + organization: + type: string + description: The organization for the IP address. GeoLite City does not include this field. + InsightsTraits: + description: General traits for an IP address, including the fields the Insights response adds beyond City Plus. + allOf: + - $ref: '#/components/schemas/CityTraits' + - type: object + properties: + ip_risk_snapshot: + type: number + minimum: 0.01 + maximum: 99 + description: A snapshot of the risk for the IP address, from 0.01 to 99. A higher value means higher risk. This score changes less often than the equivalent minFraud score and does not respond to traffic on your network. MaxMind omits this field when it has no signals for the network or when the signals show the network is low risk. + is_anonymous: + type: boolean + deprecated: true + description: Deprecated. True if the IP address belongs to any anonymous network. Moved to the `anonymizer` object. Kept here for backward compatibility. + is_anonymous_vpn: + type: boolean + deprecated: true + description: Deprecated. True if the IP address belongs to an anonymous VPN provider. Moved to the `anonymizer` object. Kept here for backward compatibility. + is_hosting_provider: + type: boolean + deprecated: true + description: Deprecated. True if the IP address belongs to a hosting provider. Moved to the `anonymizer` object. Kept here for backward compatibility. + is_public_proxy: + type: boolean + deprecated: true + description: Deprecated. True if the IP address belongs to a public proxy. Moved to the `anonymizer` object. Kept here for backward compatibility. + is_residential_proxy: + type: boolean + deprecated: true + description: Deprecated. True if the IP address is on a suspected anonymizing network and belongs to a residential ISP. This excludes peer-to-peer proxy IP addresses. Moved to the `anonymizer` object. Kept here for backward compatibility. + is_tor_exit_node: + type: boolean + deprecated: true + description: Deprecated. True if the IP address is a Tor exit node. Moved to the `anonymizer` object. Kept here for backward compatibility. + static_ip_score: + type: number + minimum: 0 + maximum: 99.99 + description: How static the IP address is, from 0 to 99.99. A higher value means a more static address. + user_count: + type: integer + minimum: 0 + description: The estimated number of users on the IP address or network in the past 24 hours. For IPv4, this counts the single IP address. For IPv6, this counts the /64 network. + user_type: + type: string + description: 'The user type for the IP address. Known values: `business`, `cafe`, `cellular`, `college`, `consumer_privacy_network`, `content_delivery_network`, `government`, `hosting`, `library`, `military`, `residential`, `router`, `school`, `search_engine_spider`, `traveler`.' + InsightsIPAddress: + type: object + description: IP intelligence for the IP address, as returned by minFraud Insights and Factors. This is the GeoIP Insights response body, with `risk` and `risk_reasons` added, `is_high_risk` added to `country`, `local_time` added to `location`, and no `maxmind` object. Every field can be absent if MaxMind has no data for the IP address. + properties: + anonymizer: + $ref: '#/components/schemas/Anonymizer' + description: Anonymizer data for the IP address. + city: + $ref: '#/components/schemas/CityWithConfidence' + description: The city for the IP address. + continent: + $ref: '#/components/schemas/Continent' + description: The continent for the IP address. + country: + $ref: '#/components/schemas/InsightsIPAddressCountry' + description: The country where MaxMind believes the IP address's user is located. + location: + $ref: '#/components/schemas/InsightsIPAddressLocation' + description: Location details for the IP address. + postal: + $ref: '#/components/schemas/PostalWithConfidence' + description: The postal code for the IP address. + registered_country: + $ref: '#/components/schemas/Country' + description: The country where the ISP registered the IP address. + represented_country: + $ref: '#/components/schemas/RepresentedCountry' + risk: + type: number + minimum: 0.01 + maximum: 99 + description: The risk for the IP address, from 0.01 to 99. A higher value means higher risk. + risk_reasons: + type: array + description: Why the IP address received its risk. + items: + $ref: '#/components/schemas/IPRiskReason' + subdivisions: + type: array + description: The subdivisions of the country associated with the IP address, ordered from largest to smallest. + items: + $ref: '#/components/schemas/SubdivisionWithConfidence' + traits: + $ref: '#/components/schemas/InsightsTraits' + description: General traits for the IP address. + ShippingAddressInsights: + description: minFraud risk data about a shipping address. + allOf: + - $ref: '#/components/schemas/AddressInsights' + - type: object + properties: + distance_to_billing_address: + type: integer + description: The distance, in kilometers, from the shipping address to the billing address. When MaxMind cannot locate an address more precisely, it uses country or subdivision coordinates, which can make this distance inaccurate. + is_high_risk: + type: boolean + description: True if MaxMind associates the shipping address with fraudulent transactions. Present only when a shipping address was given. + Insights: + description: The minFraud Insights response. It has every field in the Score response, plus more IP intelligence and risk factor data. + allOf: + - $ref: '#/components/schemas/ScoreBase' + - type: object + properties: + billing_address: + $ref: '#/components/schemas/AddressInsights' + description: Data about the billing address. + billing_phone: + $ref: '#/components/schemas/Phone' + description: Data about the billing phone number. + credit_card: + $ref: '#/components/schemas/ResponseCreditCard' + description: Data about the credit card. Present only when the request includes an issuer ID number. + device: + $ref: '#/components/schemas/ResponseDevice' + description: Data about the device MaxMind associates with the IP address in the request. + email: + $ref: '#/components/schemas/ResponseEmail' + description: Email intelligence data. + ip_address: + $ref: '#/components/schemas/InsightsIPAddress' + description: IP intelligence data. + shipping_address: + $ref: '#/components/schemas/ShippingAddressInsights' + description: Data about the shipping address. + shipping_phone: + $ref: '#/components/schemas/Phone' + description: Data about the shipping phone number. + CodeAndReason: + type: object + description: 'A machine-readable code and a human-readable reason for part of the risk score. MaxMind can add codes. Known examples: `ANONYMOUS_IP`, `COUNTRY`, `ORG_DISTANCE_RISK`.' + properties: + code: + type: string + maxLength: 255 + description: A machine-readable code that identifies the reason. + reason: + type: string + description: A human-readable explanation of the reason. The text can change at any time. + RiskScoreReason: + type: object + description: A reason for part of the risk score. Usually present only for a medium to high risk transaction. + properties: + multiplier: + type: number + minimum: 0.01 + maximum: 100 + description: The factor by which the reasons in `reasons` change the risk score. A value above 1 raises the score. A value below 1 lowers it. + reasons: + type: array + description: The reasons for the multiplier. + items: + $ref: '#/components/schemas/CodeAndReason' + Factors: + description: The minFraud Factors response. It has every field in the Insights response, plus the risk score reasons. + allOf: + - $ref: '#/components/schemas/Insights' + - type: object + properties: + risk_score_reasons: + type: array + description: The reasons for the risk score. Usually present only for a medium to high risk transaction. Not present when no reason changed the score significantly. + items: + $ref: '#/components/schemas/RiskScoreReason' + TransactionReport: + type: object + description: A report of a transaction as fraud, legitimate, or another outcome. You must give at least one of `ip_address`, `maxmind_id`, `minfraud_id`, and `transaction_id`. Give as many of them as you have. This helps MaxMind match the report to the original transaction. + required: + - tag + additionalProperties: false + anyOf: + - required: + - ip_address + - required: + - maxmind_id + - required: + - minfraud_id + - required: + - transaction_id + properties: + chargeback_code: + type: string + description: The reason code your payment processor gives for a chargeback. + ip_address: + type: string + anyOf: + - format: ipv4 + - format: ipv6 + description: The IP address of the customer placing the order. + maxmind_id: + type: string + pattern: ^[0-9A-Z]{8}$ + description: The eight-character ID for a minFraud Legacy request. MaxMind returns this in the `maxmindID` field of a minFraud Legacy response. The value must be one MaxMind returned. The value is case sensitive and has only digits and uppercase letters. + minfraud_id: + type: string + format: uuid + description: The minFraud ID for a minFraud Score, Insights, or Factors request. MaxMind returns this at `/id` in the response. + notes: + type: string + maxLength: 1000 + description: Your notes on the tag for this transaction. + tag: + type: string + enum: + - chargeback + - clear + - not_fraud + - spam_or_abuse + - suspected_fraud + description: |- + How likely you believe the transaction is to be fraudulent. + + - `chargeback`: associate a chargeback with the transaction. + - `clear`: retract a previous report, because the initial classification was incorrect. + - `not_fraud`: the transaction was a false positive. + - `spam_or_abuse`: the transaction was linked to spam or abuse. + - `suspected_fraud`: a high-risk transaction where fraud has not yet been confirmed. + transaction_id: + type: string + minLength: 1 + description: The transaction ID you gave in the original minFraud request. + DispositionUpdate: + type: object + required: + - minfraud_id + properties: + action: + type: + - string + - 'null' + description: 'The transaction''s most recent disposition action. Known values: `accept`, `reject`, `manual_review`, and `expired_review`, which means the one-week manual review period expired before review.' + action_last_updated: + type: + - string + - 'null' + format: date-time + description: The date and time the disposition action was last updated, in RFC 3339 format with microsecond precision. + minfraud_id: + type: string + format: uuid + description: The transaction's minFraud ID. + note: + type: + - string + - 'null' + maxLength: 500 + description: The transaction's most recent note. Null if no note is set. + note_last_updated: + type: + - string + - 'null' + format: date-time + description: The date and time the note was last updated, in RFC 3339 format with microsecond precision. Null if the transaction never had a note. + DispositionUpdatesResponse: + type: object + required: + - last_update_timestamp + - updates + properties: + last_update_timestamp: + type: string + format: date-time + description: The sort timestamp of the last transaction in `updates`, in RFC 3339 format with microsecond precision. This can differ from that transaction's `action_last_updated` and `note_last_updated`. Pass this value as `updates_after` in your next request. An empty `updates` array means there are no updates after `updates_after` yet. This value is then not a transaction's timestamp, so keep your current `updates_after` for the next request. + updates: + type: array + description: The transactions with a disposition or note update after `updates_after`, including a transaction whose manual review period expired. MaxMind sorts by the earliest update timestamp, either the disposition or the note, after `updates_after`. A response usually holds at most 1000 updated transactions. Do not rely on this limit. A transaction can appear in more than one response, for example when its note changes after its disposition, so process updates idempotently. + items: + $ref: '#/components/schemas/DispositionUpdate' + examples: + request: + summary: minFraud request body + value: + account: + user_id: '3132' + username_md5: 570a90bfbf8c7eab5dc5d4e26832d5b1 + billing: + address: 400 Blake St. + address_2: Suite 5 + city: New Haven + company: Big Corp. + country: US + first_name: John + last_name: Doe + phone_country_code: '1' + phone_number: 203-000-0000 + postal: '06511' + region: CT + credit_card: + avs_result: 'Y' + bank_name: Bank of America + bank_phone_country_code: '1' + bank_phone_number: 800-342-1232 + country: US + cvv_result: 'N' + issuer_id_number: '323132' + last_digits: '7643' + token: OQRST14PLQ98323 + was_3d_secure_successful: true + custom_inputs: + a_custom_input_key: NSC0083121 + another_custom_input_key: false + device: + accept_language: en-US,en;q=0.8 + ip_address: 2001:db8::ff00:42:8329 + session_age: 3600.5 + session_id: c2ffa1b7-f5c5-4702-beb2-4254794fe391 + user_agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36 + email: + address: 977577b140bfb7c516e4746204fbdb01 + domain: maxmind.com + event: + party: customer + shop_id: s2123 + transaction_id: txn3134133 + type: purchase + order: + affiliate_id: af12 + amount: 323.21 + currency: USD + discount_code: FIRST + has_gift_message: false + is_gift: true + referrer_uri: http://www.google.com/ + subaffiliate_id: saf42 + payment: + decline_code: card_declined + method: card + processor: stripe + was_authorized: false + shipping: + address: 82 Wall St. + address_2: '#1' + city: New Haven + company: Smaller, Inc. + country: US + delivery_speed: same_day + first_name: Jane + last_name: Doe + phone_country_code: '1' + phone_number: 203-000-0000 + postal: '06515' + region: CT + shopping_cart: + - category: pets + item_id: ad23232 + price: 20.43 + quantity: 2 + - category: beauty + item_id: bst112 + price: 100 + quantity: 1 + score: + summary: minFraud Score response + value: + disposition: + action: accept + reason: default + rule_label: my_custom_rule + funds_remaining: 25 + id: 5bc5d6c2-b2c8-40af-87f4-6d61af86b6ae + ip_address: + risk: 0.01 + queries_remaining: 5000 + risk_score: 0.01 + warnings: + - code: INPUT_INVALID + input_pointer: /shipping/city + warning: Encountered value at /shipping/city that does not meet the required constraints + score-bad-request: + summary: Score REQUEST_INVALID response + value: + code: REQUEST_INVALID + error: The request did not contain any valid input values. + error: + summary: minFraud error response + value: + code: INSUFFICIENT_FUNDS + error: You do not have sufficient funds to use this service. + insights: + summary: minFraud Insights response + value: + disposition: + action: accept + reason: default + rule_label: my_custom_rule + funds_remaining: 25 + id: 5bc5d6c2-b2c8-40af-87f4-6d61af86b6ae + ip_address: + risk: 0.01 + anonymizer: + confidence: 99 + is_anonymous: true + is_anonymous_vpn: true + is_hosting_provider: true + is_public_proxy: true + is_residential_proxy: true + is_tor_exit_node: true + network_last_seen: '2025-01-15' + provider_name: nordvpn + residential: + confidence: 82 + network_last_seen: '2026-05-11' + provider_name: quickshift + city: + confidence: 25 + geoname_id: 54321 + names: + de: Los Angeles + en: Los Angeles + es: Los Ángeles + fr: Los Angeles + ja: ロサンゼルス市 + pt-BR: Los Angeles + ru: Лос-Анджелес + zh-CN: 洛杉矶 + continent: + code: NA + geoname_id: 123456 + names: + de: Nordamerika + en: North America + es: América del Norte + fr: Amérique du Nord + ja: 北アメリカ + pt-BR: América do Norte + ru: Северная Америка + zh-CN: 北美洲 + country: + confidence: 75 + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + location: + accuracy_radius: 20 + average_income: 50321 + latitude: 37.6293 + local_time: '2015-04-26T01:37:17-08:00' + longitude: -122.1163 + metro_code: 807 + population_density: 7122 + time_zone: America/Los_Angeles + postal: + code: '90001' + confidence: 10 + registered_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + represented_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + type: military + risk_reasons: + - code: ANONYMOUS_IP + reason: The IP address belongs to an anonymous network. + - code: MINFRAUD_NETWORK_ACTIVITY + reason: Suspicious activity has been seen on this IP address across minFraud customers. + subdivisions: + - confidence: 50 + geoname_id: 5332921 + iso_code: CA + names: + de: Kalifornien + en: California + es: California + fr: Californie + ja: カリフォルニア + ru: Калифорния + zh-CN: 加州 + traits: + autonomous_system_number: 1239 + autonomous_system_organization: Linkem IR WiMax Network + connection_type: Cable/DSL + domain: example.com + ip_address: 1.2.3.4 + ip_risk_snapshot: 45.5 + is_anonymous: true + is_anonymous_vpn: true + is_anycast: true + is_hosting_provider: true + is_public_proxy: true + is_residential_proxy: true + is_tor_exit_node: true + isp: Linkem spa + mobile_country_code: '310' + mobile_network_code: '004' + network: 1.2.3.0/24 + organization: Linkem IR WiMax Network + static_ip_score: 1.5 + user_count: 1 + user_type: traveler + queries_remaining: 5000 + risk_score: 0.01 + warnings: + - code: INPUT_INVALID + input_pointer: /shipping/city + warning: Encountered value at /shipping/city that does not meet the required constraints + billing_address: + distance_to_ip_location: 100 + is_in_ip_country: true + is_postal_in_city: true + latitude: 37.545 + longitude: -122.421 + billing_phone: + country: US + is_voip: true + matches_postal: true + network_operator: Verizon/1 + number_type: fixed + credit_card: + brand: Visa + country: US + is_business: true + is_issued_in_billing_address_country: true + is_prepaid: true + is_virtual: true + issuer: + matches_provided_name: true + matches_provided_phone_number: true + name: Bank of America + phone_number: 800-732-9194 + type: credit + device: + confidence: 99 + id: 7835b099-d385-4e5b-969e-7df26181d73b + last_seen: '2016-06-08T14:16:38Z' + local_time: '2018-01-02T10:40:11-08:00' + email: + domain: + classification: business + first_seen: '2015-01-20' + risk: 1.23 + visit: + has_redirect: true + last_visited_on: '2025-11-15' + status: live + volume: 6.5 + first_seen: '2016-02-03' + is_disposable: false + is_free: false + is_high_risk: true + shipping_address: + distance_to_billing_address: 22 + distance_to_ip_location: 15 + is_high_risk: true + is_in_ip_country: true + is_postal_in_city: true + latitude: 37.632 + longitude: -122.313 + shipping_phone: + country: CA + is_voip: true + matches_postal: true + network_operator: Telus Mobility-SVR/2 + number_type: mobile + factors: + summary: minFraud Factors response + value: + disposition: + action: accept + reason: default + rule_label: my_custom_rule + funds_remaining: 25 + id: 5bc5d6c2-b2c8-40af-87f4-6d61af86b6ae + ip_address: + risk: 0.01 + anonymizer: + confidence: 99 + is_anonymous: true + is_anonymous_vpn: true + is_hosting_provider: true + is_public_proxy: true + is_residential_proxy: true + is_tor_exit_node: true + network_last_seen: '2025-01-15' + provider_name: nordvpn + residential: + confidence: 82 + network_last_seen: '2026-05-11' + provider_name: quickshift + city: + confidence: 25 + geoname_id: 54321 + names: + de: Los Angeles + en: Los Angeles + es: Los Ángeles + fr: Los Angeles + ja: ロサンゼルス市 + pt-BR: Los Angeles + ru: Лос-Анджелес + zh-CN: 洛杉矶 + continent: + code: NA + geoname_id: 123456 + names: + de: Nordamerika + en: North America + es: América del Norte + fr: Amérique du Nord + ja: 北アメリカ + pt-BR: América do Norte + ru: Северная Америка + zh-CN: 北美洲 + country: + confidence: 75 + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + location: + accuracy_radius: 20 + average_income: 50321 + latitude: 37.6293 + local_time: '2015-04-26T01:37:17-08:00' + longitude: -122.1163 + metro_code: 807 + population_density: 7122 + time_zone: America/Los_Angeles + postal: + code: '90001' + confidence: 10 + registered_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + represented_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + type: military + risk_reasons: + - code: ANONYMOUS_IP + reason: The IP address belongs to an anonymous network. + - code: MINFRAUD_NETWORK_ACTIVITY + reason: Suspicious activity has been seen on this IP address across minFraud customers. + subdivisions: + - confidence: 50 + geoname_id: 5332921 + iso_code: CA + names: + de: Kalifornien + en: California + es: California + fr: Californie + ja: カリフォルニア + ru: Калифорния + zh-CN: 加州 + traits: + autonomous_system_number: 1239 + autonomous_system_organization: Linkem IR WiMax Network + connection_type: Cable/DSL + domain: example.com + ip_address: 1.2.3.4 + ip_risk_snapshot: 45.5 + is_anonymous: true + is_anonymous_vpn: true + is_anycast: true + is_hosting_provider: true + is_public_proxy: true + is_residential_proxy: true + is_tor_exit_node: true + isp: Linkem spa + mobile_country_code: '310' + mobile_network_code: '004' + network: 1.2.3.0/24 + organization: Linkem IR WiMax Network + static_ip_score: 1.5 + user_count: 1 + user_type: traveler + queries_remaining: 5000 + risk_score: 0.01 + warnings: + - code: INPUT_INVALID + input_pointer: /shipping/city + warning: Encountered value at /shipping/city that does not meet the required constraints + billing_address: + distance_to_ip_location: 100 + is_in_ip_country: true + is_postal_in_city: true + latitude: 37.545 + longitude: -122.421 + billing_phone: + country: US + is_voip: true + matches_postal: true + network_operator: Verizon/1 + number_type: fixed + credit_card: + brand: Visa + country: US + is_business: true + is_issued_in_billing_address_country: true + is_prepaid: true + is_virtual: true + issuer: + matches_provided_name: true + matches_provided_phone_number: true + name: Bank of America + phone_number: 800-732-9194 + type: credit + device: + confidence: 99 + id: 7835b099-d385-4e5b-969e-7df26181d73b + last_seen: '2016-06-08T14:16:38Z' + local_time: '2018-01-02T10:40:11-08:00' + email: + domain: + classification: business + first_seen: '2015-01-20' + risk: 1.23 + visit: + has_redirect: true + last_visited_on: '2025-11-15' + status: live + volume: 6.5 + first_seen: '2016-02-03' + is_disposable: false + is_free: false + is_high_risk: true + shipping_address: + distance_to_billing_address: 22 + distance_to_ip_location: 15 + is_high_risk: true + is_in_ip_country: true + is_postal_in_city: true + latitude: 37.632 + longitude: -122.313 + shipping_phone: + country: CA + is_voip: true + matches_postal: true + network_operator: Telus Mobility-SVR/2 + number_type: mobile + risk_score_reasons: + - multiplier: 45 + reasons: + - code: ANONYMOUS_IP + reason: The Anonymous IP address raised the overall risk score + - multiplier: 1.6 + reasons: + - code: ORG_DISTANCE_RISK + reason: The risk of the ISP combined with the distance between the billing address and IP address location raised the overall risk score + - multiplier: 0.34 + reasons: + - code: PHONE_ACTIVITY + reason: minFraud network activity of the phone number lowered the overall risk score + transaction-report: + summary: Transaction report request + value: + ip_address: 1.2.3.4 + tag: suspected_fraud + transaction_id: '1' + report-bad-request: + summary: Report a Transaction TAG_REQUIRED response + value: + code: TAG_REQUIRED + error: Your request does not include a tag field. + disposition-updates: + summary: Disposition updates response + value: + last_update_timestamp: '2017-03-15T22:06:22.492945Z' + updates: + - minfraud_id: deadbeef-0000-0000-0000-000000000003 + action: manual_review + action_last_updated: '2017-03-04T20:14:42.757200Z' + note: null + note_last_updated: '2017-03-05T16:52:31.995250Z' + - minfraud_id: deadbeef-0000-0000-0000-000000000002 + action: reject + action_last_updated: '2017-03-14T21:39:57.854300Z' + note: null + note_last_updated: '2017-03-15T11:37:42.83235Z' + - minfraud_id: deadbeef-0000-0000-0000-000000000000 + action: accept + action_last_updated: '2017-03-14T22:04:01.04425Z' + note: null + note_last_updated: null + - minfraud_id: deadbeef-0000-0000-0000-000000000020 + action: manual_review + action_last_updated: '2017-03-15T22:04:11.044250Z' + note: Panda, can you check this out? + note_last_updated: '2017-03-15T22:04:25.828250Z' + - minfraud_id: deadbeef-0000-0000-0000-000000000030 + action: accept + action_last_updated: '2017-03-15T22:05:42.954231Z' + note: Customer was traveling abroad. + note_last_updated: '2017-03-15T22:05:58.132423Z' + - minfraud_id: deadbeef-0000-0000-0000-000000000050 + action: expired_review + action_last_updated: '2017-03-15T22:06:22.492945Z' + note: Customer didn't answer several phone calls. + note_last_updated: '2017-03-15T22:06:56.848123Z' + disposition-bad-request: + summary: Dispositions UPDATES_AFTER_REQUIRED response + value: + code: UPDATES_AFTER_REQUIRED + error: You have not supplied the updates_after URI parameter. diff --git a/components/minfraud-request.yaml b/components/minfraud-request.yaml new file mode 100644 index 0000000..dda8136 --- /dev/null +++ b/components/minfraud-request.yaml @@ -0,0 +1,734 @@ +schemas: + Request: + type: object + description: >- + The minFraud request body. Score, Insights, and Factors accept the same + request body. Every object is optional. Add more fields to improve + accuracy. + + + MaxMind can add fields to the request body without a version change. A + field that MaxMind does not recognize produces an `INPUT_UNKNOWN` warning. + + + A string field allows up to 255 valid Unicode characters unless its schema + states a shorter limit. Null and newline characters are not allowed. + MaxMind accepts a number sent as a string and a string sent as a number, + and converts it to the type the field requires. + + + A value that does not meet a field's constraints, such as its pattern, + enum, or length, produces an `INPUT_INVALID` warning in the response. The + request still succeeds. + minProperties: 1 + properties: + account: + $ref: "#/schemas/Account" + description: Information about the account involved in the event. + billing: + $ref: "#/schemas/Address" + description: The billing address for the order. + credit_card: + $ref: "#/schemas/CreditCard" + description: Information about the credit card used. + custom_inputs: + $ref: "#/schemas/CustomInputs" + device: + $ref: "#/schemas/Device" + description: Information about the device used in the transaction. + email: + $ref: "#/schemas/Email" + description: Information about the email used in the transaction. + event: + $ref: "#/schemas/Event" + description: General information about the event being scored. + order: + $ref: "#/schemas/Order" + description: Information about the order. + payment: + $ref: "#/schemas/Payment" + description: Information about the payment method used. + shipping: + $ref: "#/schemas/Shipping" + description: The shipping address for the order. + shopping_cart: + type: array + description: The items purchased in the order. + items: + $ref: "#/schemas/ShoppingCartItem" + Device: + type: object + properties: + accept_language: + type: string + maxLength: 255 + description: The HTTP `Accept-Language` header of the device. + ip_address: + type: string + maxLength: 255 + description: >- + The IPv4 or IPv6 address of the device, in presentation format + (dotted-quad notation or IPv6 colon notation). A private or reserved + address produces an `IP_ADDRESS_RESERVED` warning. + session_age: + type: number + minimum: 0 + maximum: 9999999999999 + description: >- + The number of seconds between the creation of the user's session and + the transaction. This is not the length of the current visit. It is + the time since the start of the first visit. + session_id: + type: string + maxLength: 255 + description: An ID that identifies a visitor's session on the site. + tracking_token: + type: string + description: >- + The token that the Device Tracking Add-On client-side code returns for + explicit device linking. + user_agent: + type: string + maxLength: 512 + description: The HTTP `User-Agent` header of the browser used. + Event: + type: object + properties: + party: + type: string + enum: + - agent + - customer + description: The party that submits the transaction. + shop_id: + type: string + maxLength: 255 + description: >- + Your internal ID for the shop, affiliate, or merchant the order comes + from. Required for a reseller, payment provider, gateway, or affiliate + network. If you are testing the minFraud service, prefix your shop ID + with `test`, or set it to `test`. + time: + type: string + format: date-time + description: >- + The time the event occurred, in RFC 3339 format. If you omit this + field, MaxMind uses the time it receives the request. Do not send this + field for a live transaction. Use it only for a stored transaction + that you score later. + + + The time must be within the past year. For an older time, MaxMind uses + the current time to score the transaction and returns a warning. + transaction_id: + type: string + maxLength: 255 + description: Your internal ID for the transaction. + type: + type: string + enum: + - account_creation + - account_login + - credit_application + - email_change + - fund_transfer + - password_reset + - payout_change + - purchase + - recurring_purchase + - referral + - sim_swap + - survey + description: >- + The type of event being scored. + + + - `account_creation`: the transactor is creating an account. + + - `account_login`: the transactor is logging in to an account. + + - `credit_application`: the transactor is applying for credit. + + - `email_change`: the transactor is changing the email address on an + account. + + - `fund_transfer`: the transactor is transferring funds between + accounts. + + - `password_reset`: the transactor is resetting a password. + + - `payout_change`: the transactor is changing how you pay them. Use + this for any case where you pay your users and they change how you pay + them, such as a referral or survey payout. + + - `purchase`: the transactor is making a purchase. + + - `recurring_purchase`: the transactor is setting up a recurring + purchase or subscription. + + - `referral`: the transactor is sending you referral traffic, for + example by referring someone to your site with an ad. + + - `sim_swap`: for a mobile network operator. A new SIM card or eSIM is + being issued for a customer's existing phone number. + + - `survey`: the transactor is starting or completing a survey. + Account: + type: object + properties: + user_id: + type: string + maxLength: 255 + description: >- + Your internal ID for the account. Use an ID that does not change, not + a login name that can change. This is not your MaxMind account ID. + username_md5: + type: string + pattern: "^[0-9a-fA-F]{32}$" + description: An MD5 hash of the account username. + Email: + type: object + properties: + address: + type: string + maxLength: 255 + description: >- + The email address, or the MD5 hash of the normalized email address. + Normalize the address before you hash it. See + https://dev.maxmind.com/minfraud/normalizing-email-addresses-for-minfraud. + A plaintext address must be a valid email address. MaxMind lowercases + it, converts an internationalized domain to ASCII, and fixes a few + common typos, such as a misspelled `gmail.com`. + domain: + type: string + maxLength: 255 + description: >- + The domain of the email address. Do not include the `@`. You do not + need to send this field unless you send the email address as an MD5 + hash. MaxMind lowercases the domain, converts an internationalized + domain to ASCII, and fixes a few common typos. + Address: + type: object + description: A billing or shipping address. + properties: + address: + type: string + maxLength: 255 + description: The first line of the street address. + address_2: + type: string + maxLength: 255 + description: The second line of the street address. + city: + type: string + maxLength: 255 + company: + type: string + maxLength: 255 + description: The company name for the address. + country: + type: string + pattern: "^[A-Z]{2}$" + description: >- + The two-character ISO 3166-1 alpha-2 country code. + first_name: + type: string + maxLength: 255 + last_name: + type: string + maxLength: 255 + phone_country_code: + type: string + pattern: "^[0-9]{1,4}$" + description: The international calling code for the phone number. + phone_number: + type: string + maxLength: 255 + description: >- + The phone number, without the country code. MaxMind strips punctuation + characters. After that, the number must contain only digits. + postal: + type: string + maxLength: 255 + description: The postal code for the address. + region: + type: string + pattern: "^[0-9A-Z]{1,4}$" + description: The ISO 3166-2 subdivision code. + Shipping: + description: A shipping address, with the delivery speed for the order. + allOf: + - $ref: "#/schemas/Address" + - type: object + properties: + delivery_speed: + type: string + enum: + - same_day + - overnight + - expedited + - standard + description: The shipping speed selected for the order. + Payment: + type: object + properties: + decline_code: + type: string + maxLength: 255 + description: >- + The decline code the payment processor returned. Omit this field if + the transaction was not declined. + method: + type: string + enum: + - bank_debit + - bank_redirect + - bank_transfer + - buy_now_pay_later + - card + - crypto + - digital_wallet + - gift_card + - real_time_payment + - rewards + description: >- + The payment method. + + + - `bank_debit`: a direct debit of the customer's bank account. + + - `bank_redirect`: the customer authorizes payment after + authenticating with their bank. + + - `bank_transfer`: the customer pushes funds directly from their bank + account. + + - `buy_now_pay_later`: payment through a buy now, pay later provider, + such as Affirm, Afterpay, or Klarna. + + - `card`: payment by a credit, debit, or charge card. + + - `crypto`: payment with a cryptocurrency. + + - `digital_wallet`: payment from a digital wallet linked to a card or + bank account, such as Apple Pay, Google Pay, or PayPal. + + - `gift_card`: payment with a merchant-sponsored gift card. + + - `real_time_payment`: the customer pushes funds directly from their + bank account or another funding source, using an intermediary such as + a phone number to authenticate, for example Pix, PayNow, or Swish. + + - `rewards`: payment with rewards or loyalty program incentives. + processor: + type: string + description: The payment processor used for the transaction. + enum: + - adyen + - affirm + - afterpay + - altapay + - amazon_payments + - american_express_payment_gateway + - apple_pay + - aps_payments + - authorizenet + - balanced + - banquest + - beanstream + - bluepay + - bluesnap + - boacompra + - boku + - bpoint + - braintree + - cardknox + - cardpay + - cashfree + - ccavenue + - ccnow + - cetelem + - chase_paymentech + - checkout_com + - cielo + - collector + - commdoo + - compropago + - concept_payments + - conekta + - coregateway + - creditguard + - credorax + - cryptomus + - ct_payments + - cuentadigital + - curopayments + - cybersource + - dalenys + - dalpay + - datacap + - datacash + - dibs + - digital_river + - dlocal + - dotpay + - ebs + - ecomm365 + - ecommpay + - elavon + - emerchantpay + - epay + - epayco + - eprocessing_network + - epx + - eway + - exact + - fat_zebra + - first_atlantic_commerce + - first_data + - fiserv + - g2a_pay + - global_payments + - gocardless + - google_pay + - heartland + - hipay + - ingenico + - interac + - internetsecure + - intuit_quickbooks_payments + - iugu + - klarna + - komoju + - lemon_way + - mastercard_payment_gateway + - mercadopago + - mercanet + - merchant_esolutions + - mirjeh + - mollie + - moneris_solutions + - neopay + - neosurf + - nmi + - oceanpayment + - oney + - onpay + - openbucks + - openpaymx + - optimal_payments + - orangepay + - other + - pacnet_services + - payconex + - payeezy + - payfast + - paygate + - paylike + - payment_express + - paymentwall + - payone + - paypal + - payplus + - paysafecard + - paysera + - paystation + - paytm + - paytrace + - paytrail + - payture + - payu + - payulatam + - payvision + - payway + - payza + - pinpayments + - placetopay + - posconnect + - princeton_payment_solutions + - psigate + - pxp_financial + - qiwi + - quickpay + - raberil + - razorpay + - rede + - redpagos + - rewardspay + - safecharge + - sagepay + - securepay + - securetrading + - shopify_payments + - simplify_commerce + - skrill + - smartcoin + - smartdebit + - solidtrust_pay + - sps_decidir + - stripe + - summit_payments + - synapsefi + - systempay + - telerecargas + - towah + - transact_pro + - trustly + - trustpay + - tsys + - usa_epay + - vantiv + - verepay + - vericheck + - vindicia + - virtual_card_services + - vme + - vpos + - windcave + - wirecard + - worldpay + - yaadpay + was_authorized: + type: boolean + description: >- + Whether the payment was authorized. Omit this field if the transaction + has not yet been approved or denied. + CreditCard: + type: object + properties: + avs_result: + type: string + pattern: "^[A-Za-z1-4]$" + description: >- + The address verification system (AVS) check result, as your payment + processor returns it. MaxMind supports the standard AVS codes. + bank_name: + type: string + maxLength: 255 + description: The name of the bank that issued the credit card. + bank_phone_country_code: + type: string + pattern: "^[0-9]{1,4}$" + description: The international calling code for the bank's phone number. + bank_phone_number: + type: string + maxLength: 255 + description: >- + The bank's phone number, without the country code. MaxMind strips + punctuation characters. After that, the number must contain only + digits. + country: + type: string + pattern: "^[A-Z]{2}$" + description: >- + The two-character ISO 3166-1 country code of the card issuer's + location. You can send this instead of `issuer_id_number` if you do + not want to send partial account numbers, or if your payment processor + does not provide them. + cvv_result: + type: string + pattern: "^[A-Za-z0-9]$" + description: >- + The card verification value (CVV) check result, as your payment + processor returns it. + issuer_id_number: + type: string + pattern: "^([0-9]{6}|[0-9]{8})$" + description: >- + The first 6 or 8 digits of the credit card number. If you do not know + whether the number is 6 or 8 digits long, send 6 digits. + last_digits: + type: string + pattern: "^([0-9]{2}|[0-9]{4})$" + description: >- + The last 2 or 4 digits of the credit card number. Send the last 4 + digits in most cases. If `issuer_id_number` has 8 digits and the card + brand is not Discover, JCB, Mastercard, UnionPay, or Visa, send the + last 2 digits. + token: + type: string + maxLength: 255 + pattern: "^[!-~]+$" + not: + pattern: "^[0-9]{1,19}$" + description: >- + A token that uniquely identifies the card, for example one your + payment processor gives you. The token must consist of non-space + printable ASCII characters. If the token is all digits, it must be + more than 19 characters long. The token must not be a primary account + number (PAN) or a simple transformation of one. If a valid token looks + like a PAN but is not one, you can prefix it with a fixed string, for + example `token-`. + was_3d_secure_successful: + type: boolean + description: >- + Whether the 3-D Secure check for the transaction was successful. Omit + this field if 3-D Secure verification was not used, was unavailable, + or had another outcome besides success or failure. + Order: + type: object + properties: + affiliate_id: + type: string + maxLength: 255 + description: Your internal ID for the affiliate that referred the order. + amount: + type: number + minimum: 0 + maximum: 9999999999999 + description: >- + The total order amount before taxes and discounts, in the currency + given in `currency`. + currency: + type: string + pattern: "^[A-Z]{3}$" + description: The ISO 4217 currency code for the order amount. + discount_code: + type: string + maxLength: 255 + description: >- + The discount code applied to the order. Separate multiple discount + codes with a comma. + has_gift_message: + type: boolean + description: Whether the order included a gift message. + is_gift: + type: boolean + description: Whether the order was marked as a gift. + referrer_uri: + type: string + maxLength: 1024 + format: uri + description: >- + The URI of the site that referred the customer to your site. Must be + an absolute URI with a scheme, such as `https://`. + subaffiliate_id: + type: string + maxLength: 255 + description: + Your internal ID for the subaffiliate that referred the order. + ShoppingCartItem: + type: object + description: >- + An item purchased in the order. You can hash `category` and `item_id` with + a cryptographic hash function and a fixed salt to protect customer + privacy. Do not use a random salt. A random salt produces a different hash + each time for the same value, which defeats fraud detection. + properties: + category: + type: string + maxLength: 255 + description: The category of the item. This can be a hashed value. + item_id: + type: string + maxLength: 255 + description: Your internal ID for the item. This can be a hashed value. + price: + type: number + minimum: 0 + maximum: 9999999999999 + description: >- + The per-unit price of the item. This should use the same currency as + the order's `currency`. + quantity: + type: integer + minimum: 0 + maximum: 9999999999999 + description: The quantity of the item purchased. + CustomInputs: + type: object + description: >- + Values for the custom inputs that you configure for your account. + Configure each key first, from Custom Inputs in the account portal. Each + key must match a key configured for your account, and the value must match + the type configured for that key: a boolean, a number from -9999999999999 + to 9999999999999, a string of up to 255 characters, or a phone number + string of up to 255 characters. MaxMind strips spaces and punctuation from + a phone number, and the rest must be digits. A key that your account does + not have configured produces an `INPUT_UNKNOWN` warning. Do not send a + full credit card number as a value. MaxMind rejects it and returns a + warning. + additionalProperties: + oneOf: + - type: boolean + - type: number + minimum: -9999999999999 + maximum: 9999999999999 + - type: string + maxLength: 255 + TransactionReport: + type: object + description: >- + A report of a transaction as fraud, legitimate, or another outcome. You + must give at least one of `ip_address`, `maxmind_id`, `minfraud_id`, and + `transaction_id`. Give as many of them as you have. This helps MaxMind + match the report to the original transaction. + required: + - tag + additionalProperties: false + anyOf: + - required: + - ip_address + - required: + - maxmind_id + - required: + - minfraud_id + - required: + - transaction_id + properties: + chargeback_code: + type: string + description: >- + The reason code your payment processor gives for a chargeback. + ip_address: + type: string + anyOf: + - format: ipv4 + - format: ipv6 + description: The IP address of the customer placing the order. + maxmind_id: + type: string + pattern: "^[0-9A-Z]{8}$" + description: >- + The eight-character ID for a minFraud Legacy request. MaxMind returns + this in the `maxmindID` field of a minFraud Legacy response. The value + must be one MaxMind returned. The value is case sensitive and has only + digits and uppercase letters. + minfraud_id: + type: string + format: uuid + description: >- + The minFraud ID for a minFraud Score, Insights, or Factors request. + MaxMind returns this at `/id` in the response. + notes: + type: string + maxLength: 1000 + description: Your notes on the tag for this transaction. + tag: + type: string + enum: + - chargeback + - clear + - not_fraud + - spam_or_abuse + - suspected_fraud + description: >- + How likely you believe the transaction is to be fraudulent. + + + - `chargeback`: associate a chargeback with the transaction. + + - `clear`: retract a previous report, because the initial + classification was incorrect. + + - `not_fraud`: the transaction was a false positive. + + - `spam_or_abuse`: the transaction was linked to spam or abuse. + + - `suspected_fraud`: a high-risk transaction where fraud has not yet + been confirmed. + transaction_id: + type: string + minLength: 1 + description: + The transaction ID you gave in the original minFraud request. diff --git a/components/minfraud-response.yaml b/components/minfraud-response.yaml new file mode 100644 index 0000000..b11dbe2 --- /dev/null +++ b/components/minfraud-response.yaml @@ -0,0 +1,712 @@ +schemas: + ScoreBase: + type: object + description: >- + The fields common to the minFraud Score, Insights, and Factors responses, + apart from `ip_address`. Score, Insights, and Factors each have a + different shape for `ip_address`. + properties: + disposition: + $ref: "#/schemas/Disposition" + description: How a custom rule disposed of the request. + funds_remaining: + type: number + minimum: 0 + description: + The approximate US dollar value of the funds left on your account. + id: + type: string + format: uuid + description: >- + The minFraud ID for this response. Use it to find the request in your + minFraud logs, or when you contact MaxMind support. + queries_remaining: + type: integer + minimum: 0 + description: >- + The approximate number of queries left for this service before your + account runs out of funds. + risk_score: + type: number + minimum: 0.01 + maximum: 99 + description: >- + The overall risk score, from 0.01 to 99. A higher score means a higher + risk of fraud. For example, a score of 20 means a 20% chance that the + transaction is fraudulent. MaxMind never returns 0 or 100, since every + transaction carries some possibility of fraud. + warnings: + type: array + description: + Issues with the request, such as an invalid or unknown input. + items: + $ref: "#/schemas/Warning" + required: + - id + - risk_score + - funds_remaining + - queries_remaining + Score: + description: The minFraud Score response. + allOf: + - $ref: "#/schemas/ScoreBase" + - type: object + properties: + ip_address: + $ref: "#/schemas/ScoreIPAddress" + description: The risk associated with the IP address. + Insights: + description: >- + The minFraud Insights response. It has every field in the Score response, + plus more IP intelligence and risk factor data. + allOf: + - $ref: "#/schemas/ScoreBase" + - type: object + properties: + billing_address: + $ref: "#/schemas/AddressInsights" + description: Data about the billing address. + billing_phone: + $ref: "#/schemas/Phone" + description: Data about the billing phone number. + credit_card: + $ref: "#/schemas/ResponseCreditCard" + description: >- + Data about the credit card. Present only when the request includes + an issuer ID number. + device: + $ref: "#/schemas/ResponseDevice" + description: >- + Data about the device MaxMind associates with the IP address in + the request. + email: + $ref: "#/schemas/ResponseEmail" + description: Email intelligence data. + ip_address: + $ref: "#/schemas/InsightsIPAddress" + description: IP intelligence data. + shipping_address: + $ref: "#/schemas/ShippingAddressInsights" + description: Data about the shipping address. + shipping_phone: + $ref: "#/schemas/Phone" + description: Data about the shipping phone number. + Factors: + description: >- + The minFraud Factors response. It has every field in the Insights + response, plus the risk score reasons. + allOf: + - $ref: "#/schemas/Insights" + - type: object + properties: + risk_score_reasons: + type: array + description: >- + The reasons for the risk score. Usually present only for a medium + to high risk transaction. Not present when no reason changed the + score significantly. + items: + $ref: "#/schemas/RiskScoreReason" + Warning: + type: object + description: >- + A warning about an issue with the request. The `code` values below are the + current set. MaxMind can add more. + + + - `BILLING_CITY_NOT_FOUND`: the billing city is not in the MaxMind + database. + + - `BILLING_COUNTRY_MISSING`: billing address fields are present but + `country` is not. + + - `BILLING_COUNTRY_NOT_FOUND`: the billing country is not in the MaxMind + database. + + - `BILLING_POSTAL_NOT_FOUND`: the billing postal code is not in the + MaxMind database. + + - `BILLING_REGION_NOT_FOUND`: the billing region is not in the MaxMind + database. + + - `EMAIL_ADDRESS_UNUSABLE`: the email address looks incorrect, so MaxMind + left it out of scoring. + + - `INPUT_INVALID`: a value does not meet the field's constraints. + + - `INPUT_UNKNOWN`: the request has a key MaxMind does not recognize. + + - `IP_ADDRESS_INVALID`: the IP address is not a valid IPv4 or IPv6 + address. + + - `IP_ADDRESS_NOT_FOUND`: MaxMind could not geolocate the IP address. + + - `IP_ADDRESS_RESERVED`: the IP address is in a reserved network. + + - `SHIPPING_CITY_NOT_FOUND`: the shipping city is not in the MaxMind + database. + + - `SHIPPING_COUNTRY_MISSING`: shipping address fields are present but + `country` is not. + + - `SHIPPING_COUNTRY_NOT_FOUND`: the shipping country is not in the MaxMind + database. + + - `SHIPPING_POSTAL_NOT_FOUND`: the shipping postal code is not in the + MaxMind database. + + - `SHIPPING_REGION_NOT_FOUND`: the shipping region is not in the MaxMind + database. + + - `TRACKING_TOKEN_INVALID`: the tracking token is malformed. + + - `TRACKING_TOKEN_NOT_FOUND`: MaxMind does not recognize the tracking + token. + + + The address warnings can reduce the accuracy of distance calculations. + properties: + code: + type: string + maxLength: 255 + input_pointer: + type: string + description: >- + A JSON Pointer to the request field the warning is about, for example + `/billing/city` or `/shopping_cart/1/price`. + warning: + type: string + description: >- + A human-readable explanation of the warning. The text can change at + any time. + Disposition: + type: object + description: >- + How a custom rule disposed of the request. Not present when your account + has no custom rules. + properties: + action: + type: string + description: >- + How MaxMind handled the request. Known values: `accept`, `reject`, + `manual_review`, `test`. MaxMind may add values. `accept` is the + default when no custom rule matches. Use `test` to test custom rules. + reason: + type: string + description: >- + Why `action` has its value. Known values: `default`, `custom_rule`. + MaxMind may add values. + rule_label: + type: string + description: >- + The label of the custom rule that was triggered. Not present when you + have no custom rules, the triggered rule has no label, or no rule was + triggered. + ScoreIPAddress: + type: object + description: The risk for the IP address, as returned by minFraud Score. + properties: + risk: + type: number + minimum: 0.01 + maximum: 99 + description: >- + The risk for the IP address, from 0.01 to 99. A higher value means + higher risk. + InsightsIPAddress: + type: object + description: >- + IP intelligence for the IP address, as returned by minFraud Insights and + Factors. This is the GeoIP Insights response body, with `risk` and + `risk_reasons` added, `is_high_risk` added to `country`, `local_time` + added to `location`, and no `maxmind` object. Every field can be absent if + MaxMind has no data for the IP address. + properties: + anonymizer: + $ref: "../components/geoip-records.yaml#/schemas/Anonymizer" + description: Anonymizer data for the IP address. + city: + $ref: "../components/geoip-records.yaml#/schemas/CityWithConfidence" + description: The city for the IP address. + continent: + $ref: "../components/geoip-records.yaml#/schemas/Continent" + description: The continent for the IP address. + country: + $ref: "#/schemas/InsightsIPAddressCountry" + description: >- + The country where MaxMind believes the IP address's user is located. + location: + $ref: "#/schemas/InsightsIPAddressLocation" + description: Location details for the IP address. + postal: + $ref: "../components/geoip-records.yaml#/schemas/PostalWithConfidence" + description: The postal code for the IP address. + registered_country: + $ref: "../components/geoip-records.yaml#/schemas/Country" + description: The country where the ISP registered the IP address. + represented_country: + $ref: "../components/geoip-records.yaml#/schemas/RepresentedCountry" + risk: + type: number + minimum: 0.01 + maximum: 99 + description: >- + The risk for the IP address, from 0.01 to 99. A higher value means + higher risk. + risk_reasons: + type: array + description: Why the IP address received its risk. + items: + $ref: "#/schemas/IPRiskReason" + subdivisions: + type: array + description: >- + The subdivisions of the country associated with the IP address, + ordered from largest to smallest. + items: + $ref: "../components/geoip-records.yaml#/schemas/SubdivisionWithConfidence" + traits: + $ref: "../components/geoip-records.yaml#/schemas/InsightsTraits" + description: General traits for the IP address. + InsightsIPAddressCountry: + description: >- + A country associated with an IP address, with MaxMind's confidence in the + result and whether MaxMind considers the country high-risk. + allOf: + - $ref: "../components/geoip-records.yaml#/schemas/CountryWithConfidence" + - type: object + properties: + is_high_risk: + type: boolean + deprecated: true + description: >- + Deprecated. True if MaxMind considers the IP address's country to + be high-risk. + InsightsIPAddressLocation: + description: >- + Location details for an IP address, including the local time at that + location. + allOf: + - $ref: "../components/geoip-records.yaml#/schemas/InsightsLocation" + - type: object + properties: + local_time: + type: string + format: date-time + description: >- + The date and time of the transaction in the time zone associated + with the IP address, in RFC 3339 format. + IPRiskReason: + type: object + description: >- + A reason why an IP address received its risk. The `code` values below are + the current set. MaxMind can add more. + + + - `ANONYMOUS_IP`: the IP address belongs to an anonymous network. + + - `BILLING_POSTAL_VELOCITY`: many billing postal codes have been seen on + this IP address. + + - `EMAIL_VELOCITY`: many email addresses have been seen on this IP + address. + + - `HIGH_RISK_DEVICE`: a high-risk device was seen on this IP address. + + - `HIGH_RISK_EMAIL`: a high-risk email address was seen on this IP address + in your past transactions. + + - `ISSUER_ID_NUMBER_VELOCITY`: many issuer ID numbers have been seen on + this IP address. + + - `MINFRAUD_NETWORK_ACTIVITY`: MaxMind has seen suspicious activity on + this IP address across minFraud customers. + properties: + code: + type: string + maxLength: 255 + reason: + type: string + description: >- + A human-readable explanation of the reason. The text can change at any + time. + AddressInsights: + type: object + description: minFraud risk data about a billing address. + properties: + distance_to_ip_location: + type: integer + description: >- + The distance, in kilometers, from the address to the IP address's + location. When MaxMind cannot locate the address or the IP address + more precisely, it uses country or subdivision coordinates, which can + make this distance inaccurate. + is_in_ip_country: + type: boolean + description: >- + True if the address is in the IP address's country. Present only when + MaxMind can geolocate the IP address and the address was given. + is_postal_in_city: + type: boolean + description: >- + True if the postal code is in the city for the address. Present only + when the postal code, city, and country were all given. MaxMind + matches the postal code against the GeoNames preferred place name for + a US ZIP code. An alternative place name for a US ZIP code might not + produce a match. + latitude: + type: number + description: >- + The approximate WGS 84 latitude for the address. The coordinates are + not precise. Do not use them to identify a street address or + household. + longitude: + type: number + description: >- + The approximate WGS 84 longitude for the address. The coordinates are + not precise. Do not use them to identify a street address or + household. + ShippingAddressInsights: + description: minFraud risk data about a shipping address. + allOf: + - $ref: "#/schemas/AddressInsights" + - type: object + properties: + distance_to_billing_address: + type: integer + description: >- + The distance, in kilometers, from the shipping address to the + billing address. When MaxMind cannot locate an address more + precisely, it uses country or subdivision coordinates, which can + make this distance inaccurate. + is_high_risk: + type: boolean + description: >- + True if MaxMind associates the shipping address with fraudulent + transactions. Present only when a shipping address was given. + Phone: + type: object + description: minFraud risk data about a billing or shipping phone number. + properties: + country: + type: string + description: + The two-character ISO 3166-1 country code for the phone number. + is_voip: + type: boolean + description: >- + True if the phone number is a VoIP number allocated by a regulator. + Present only for a valid phone number that MaxMind has data for. + matches_postal: + type: boolean + description: >- + True if the phone number's prefix is commonly associated with the + postal code. Present only for a US number when MaxMind has the + number's prefix, and the postal code and country were also given. + network_operator: + type: string + description: >- + The original network operator associated with the phone number. This + does not reflect a number ported to another operator, and it does not + identify a mobile virtual network operator. + number_type: + type: string + description: >- + The phone number's type. Known values: `fixed`, `mobile`. MaxMind may + add values. + ResponseCreditCard: + type: object + description: >- + minFraud risk data about the credit card. Present only when the request + includes an issuer ID number. + properties: + brand: + type: string + maxLength: 255 + description: 'The card brand, for example "Visa" or "Discover".' + country: + type: string + pattern: "^[A-Z]{2}$" + description: >- + The two-character ISO 3166-1 country code for the majority of + customers using this card, by billing address. If customers are spread + across countries, this is the country of the issuing bank instead. + is_business: + type: boolean + description: >- + True if the issuer ID number is for a business card. Present only when + a valid issuer ID number was given. + is_issued_in_billing_address_country: + type: boolean + description: >- + True if the billing address country matches the country of the + majority of customers using this issuer ID number. Present only when + both countries are known. When the customers for this issuer ID number + are spread across many countries, MaxMind matches against the country + of the issuing bank instead. + is_prepaid: + type: boolean + description: >- + True if the issuer ID number is for a prepaid card. Present only when + a valid issuer ID number was given. + is_virtual: + type: boolean + description: >- + True if the issuer ID number is for a virtual card. Present only when + a valid issuer ID number was given. + issuer: + $ref: "#/schemas/CreditCardIssuer" + description: Data about the bank that issued the card. + type: + type: string + description: >- + The card's type. Known values: `charge`, `credit`, `debit`. MaxMind + may add values. + CreditCardIssuer: + type: object + description: minFraud risk data about a credit card's issuing bank. + properties: + matches_provided_name: + type: boolean + description: >- + True if `name` matches the issuer name given in the request. Present + only when the request gives both a name and an issuer ID number, and + MaxMind has a name for that issuer ID number. + matches_provided_phone_number: + type: boolean + description: >- + True if `phone_number` matches the issuer phone number given in the + request. Present only when the request gives both a phone number and + an issuer ID number, and MaxMind has a phone number for that issuer ID + number. + name: + type: string + maxLength: 255 + description: The name of the issuing bank. + phone_number: + type: string + maxLength: 255 + description: >- + The phone number of the issuing bank. This number can be out of date. + ResponseDevice: + type: object + description: >- + Data about the device MaxMind associates with the IP address in the + request. + properties: + confidence: + type: number + minimum: 0.01 + maximum: 99 + description: >- + MaxMind's confidence that `id` refers to a unique device rather than a + cluster of similar devices, from 0.01 to 99. A higher value means + higher confidence. + id: + type: string + format: uuid + description: >- + MaxMind's ID for the device. Present only when the Device Tracking + Add-On is in use. + last_seen: + type: string + format: date-time + description: + The date and time MaxMind last saw the device, in RFC 3339 format. + local_time: + type: string + format: date-time + description: >- + The local date and time of the transaction in the device's time zone, + using the device's UTC offset, in RFC 3339 format. + ResponseEmail: + type: object + description: Email intelligence data. + properties: + domain: + $ref: "#/schemas/EmailDomain" + description: Data about the email domain. + first_seen: + type: string + format: date + description: >- + The date MaxMind first saw the email address. The earliest possible + date is 2008-01-01. + is_disposable: + type: boolean + description: >- + True if MaxMind believes the email address is from a disposable email + provider. Present only when the request gives a valid email address or + domain. + is_free: + type: boolean + description: >- + True if MaxMind believes the email domain is for a free provider, such + as Gmail or Yahoo! Mail. Present only when the request gives a valid + email address or domain. + is_high_risk: + type: boolean + description: >- + True if MaxMind believes the email address is likely to be used for + fraud. This is also factored into `risk_score`. Present only when the + request gives a valid email address or hash. + EmailDomain: + type: object + description: minFraud risk data about an email domain. + properties: + classification: + type: string + description: >- + A classification of the domain. Known values: `business`, `education`, + `government`, `isp_email`. MaxMind may add values. + first_seen: + type: string + format: date + description: >- + The date MaxMind first saw the email domain. The earliest possible + date is 2019-01-01. + risk: + type: number + minimum: 0.01 + maximum: 99 + description: >- + The risk associated with the domain, from 0.01 to 99. A higher value + means higher risk. + visit: + $ref: "#/schemas/EmailDomainVisit" + description: Data from an automated visit to the email domain. + volume: + type: number + minimum: 0.001 + maximum: 1000000 + description: >- + The activity MaxMind sees on this email domain across the minFraud + network, in sightings per million requests. The value is rounded to 2 + significant figures. + EmailDomainVisit: + type: object + description: >- + Data from an automated visit to the email domain. Not present for a + high-volume domain, such as one for a large email provider or business, + and can be delayed for a newly-seen domain. + properties: + has_redirect: + type: boolean + description: >- + True if the domain redirects to another URL. Absent, not `false`, when + the domain does not redirect. When true, `status` describes the domain + the visit redirected to. + last_visited_on: + type: string + format: date + description: The date of the automated visit. + status: + type: string + description: >- + The status of the domain, or of the domain a redirect led to, as of + the automated visit. Known values: `live`, `dns_error`, + `network_error`, `http_error`, `parked`, `pre_development`. MaxMind + may add values. + RiskScoreReason: + type: object + description: + A reason for part of the risk score. Usually present only for a medium to + high risk transaction. + properties: + multiplier: + type: number + minimum: 0.01 + maximum: 100 + description: >- + The factor by which the reasons in `reasons` change the risk score. A + value above 1 raises the score. A value below 1 lowers it. + reasons: + type: array + description: The reasons for the multiplier. + items: + $ref: "#/schemas/CodeAndReason" + CodeAndReason: + type: object + description: >- + A machine-readable code and a human-readable reason for part of the risk + score. MaxMind can add codes. Known examples: `ANONYMOUS_IP`, `COUNTRY`, + `ORG_DISTANCE_RISK`. + properties: + code: + type: string + maxLength: 255 + description: A machine-readable code that identifies the reason. + reason: + type: string + description: >- + A human-readable explanation of the reason. The text can change at any + time. + DispositionUpdatesResponse: + type: object + required: + - last_update_timestamp + - updates + properties: + last_update_timestamp: + type: string + format: date-time + description: >- + The sort timestamp of the last transaction in `updates`, in RFC 3339 + format with microsecond precision. This can differ from that + transaction's `action_last_updated` and `note_last_updated`. Pass this + value as `updates_after` in your next request. An empty `updates` + array means there are no updates after `updates_after` yet. This value + is then not a transaction's timestamp, so keep your current + `updates_after` for the next request. + updates: + type: array + description: >- + The transactions with a disposition or note update after + `updates_after`, including a transaction whose manual review period + expired. MaxMind sorts by the earliest update timestamp, either the + disposition or the note, after `updates_after`. A response usually + holds at most 1000 updated transactions. Do not rely on this limit. A + transaction can appear in more than one response, for example when its + note changes after its disposition, so process updates idempotently. + items: + $ref: "#/schemas/DispositionUpdate" + DispositionUpdate: + type: object + required: + - minfraud_id + properties: + action: + type: + - string + - "null" + description: >- + The transaction's most recent disposition action. Known values: + `accept`, `reject`, `manual_review`, and `expired_review`, which means + the one-week manual review period expired before review. + action_last_updated: + type: + - string + - "null" + format: date-time + description: >- + The date and time the disposition action was last updated, in RFC 3339 + format with microsecond precision. + minfraud_id: + type: string + format: uuid + description: The transaction's minFraud ID. + note: + type: + - string + - "null" + maxLength: 500 + description: >- + The transaction's most recent note. Null if no note is set. + note_last_updated: + type: + - string + - "null" + format: date-time + description: >- + The date and time the note was last updated, in RFC 3339 format with + microsecond precision. Null if the transaction never had a note. diff --git a/examples/minfraud/disposition-bad-request.yaml b/examples/minfraud/disposition-bad-request.yaml new file mode 100644 index 0000000..b44cd84 --- /dev/null +++ b/examples/minfraud/disposition-bad-request.yaml @@ -0,0 +1,4 @@ +summary: Dispositions UPDATES_AFTER_REQUIRED response +value: + code: UPDATES_AFTER_REQUIRED + error: You have not supplied the updates_after URI parameter. diff --git a/examples/minfraud/disposition-updates.yaml b/examples/minfraud/disposition-updates.yaml new file mode 100644 index 0000000..1f056d3 --- /dev/null +++ b/examples/minfraud/disposition-updates.yaml @@ -0,0 +1,34 @@ +summary: Disposition updates response +value: + last_update_timestamp: "2017-03-15T22:06:22.492945Z" + updates: + - minfraud_id: deadbeef-0000-0000-0000-000000000003 + action: manual_review + action_last_updated: "2017-03-04T20:14:42.757200Z" + note: null + note_last_updated: "2017-03-05T16:52:31.995250Z" + - minfraud_id: deadbeef-0000-0000-0000-000000000002 + action: reject + action_last_updated: "2017-03-14T21:39:57.854300Z" + note: null + note_last_updated: "2017-03-15T11:37:42.83235Z" + - minfraud_id: deadbeef-0000-0000-0000-000000000000 + action: accept + action_last_updated: "2017-03-14T22:04:01.04425Z" + note: null + note_last_updated: null + - minfraud_id: deadbeef-0000-0000-0000-000000000020 + action: manual_review + action_last_updated: "2017-03-15T22:04:11.044250Z" + note: "Panda, can you check this out?" + note_last_updated: "2017-03-15T22:04:25.828250Z" + - minfraud_id: deadbeef-0000-0000-0000-000000000030 + action: accept + action_last_updated: "2017-03-15T22:05:42.954231Z" + note: Customer was traveling abroad. + note_last_updated: "2017-03-15T22:05:58.132423Z" + - minfraud_id: deadbeef-0000-0000-0000-000000000050 + action: expired_review + action_last_updated: "2017-03-15T22:06:22.492945Z" + note: Customer didn't answer several phone calls. + note_last_updated: "2017-03-15T22:06:56.848123Z" diff --git a/examples/minfraud/error.yaml b/examples/minfraud/error.yaml new file mode 100644 index 0000000..d9f761d --- /dev/null +++ b/examples/minfraud/error.yaml @@ -0,0 +1,4 @@ +summary: minFraud error response +value: + code: INSUFFICIENT_FUNDS + error: You do not have sufficient funds to use this service. diff --git a/examples/minfraud/factors.yaml b/examples/minfraud/factors.yaml new file mode 100644 index 0000000..7500949 --- /dev/null +++ b/examples/minfraud/factors.yaml @@ -0,0 +1,222 @@ +summary: minFraud Factors response +value: + disposition: + action: accept + reason: default + rule_label: my_custom_rule + funds_remaining: 25 + id: 5bc5d6c2-b2c8-40af-87f4-6d61af86b6ae + ip_address: + risk: 0.01 + anonymizer: + confidence: 99 + is_anonymous: true + is_anonymous_vpn: true + is_hosting_provider: true + is_public_proxy: true + is_residential_proxy: true + is_tor_exit_node: true + network_last_seen: "2025-01-15" + provider_name: nordvpn + residential: + confidence: 82 + network_last_seen: "2026-05-11" + provider_name: quickshift + city: + confidence: 25 + geoname_id: 54321 + names: + de: Los Angeles + en: Los Angeles + es: Los Ángeles + fr: Los Angeles + ja: ロサンゼルス市 + pt-BR: Los Angeles + ru: Лос-Анджелес + zh-CN: 洛杉矶 + continent: + code: NA + geoname_id: 123456 + names: + de: Nordamerika + en: North America + es: América del Norte + fr: Amérique du Nord + ja: 北アメリカ + pt-BR: América do Norte + ru: Северная Америка + zh-CN: 北美洲 + country: + confidence: 75 + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + location: + accuracy_radius: 20 + average_income: 50321 + latitude: 37.6293 + local_time: "2015-04-26T01:37:17-08:00" + longitude: -122.1163 + metro_code: 807 + population_density: 7122 + time_zone: America/Los_Angeles + postal: + code: "90001" + confidence: 10 + registered_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + represented_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + type: military + risk_reasons: + - code: ANONYMOUS_IP + reason: The IP address belongs to an anonymous network. + - code: MINFRAUD_NETWORK_ACTIVITY + reason: >- + Suspicious activity has been seen on this IP address across minFraud + customers. + subdivisions: + - confidence: 50 + geoname_id: 5332921 + iso_code: CA + names: + de: Kalifornien + en: California + es: California + fr: Californie + ja: カリフォルニア + ru: Калифорния + zh-CN: 加州 + traits: + autonomous_system_number: 1239 + autonomous_system_organization: Linkem IR WiMax Network + connection_type: Cable/DSL + domain: example.com + ip_address: 1.2.3.4 + ip_risk_snapshot: 45.5 + is_anonymous: true + is_anonymous_vpn: true + is_anycast: true + is_hosting_provider: true + is_public_proxy: true + is_residential_proxy: true + is_tor_exit_node: true + isp: Linkem spa + mobile_country_code: "310" + mobile_network_code: "004" + network: 1.2.3.0/24 + organization: Linkem IR WiMax Network + static_ip_score: 1.5 + user_count: 1 + user_type: traveler + queries_remaining: 5000 + risk_score: 0.01 + warnings: + - code: INPUT_INVALID + input_pointer: /shipping/city + warning: >- + Encountered value at /shipping/city that does not meet the required + constraints + billing_address: + distance_to_ip_location: 100 + is_in_ip_country: true + is_postal_in_city: true + latitude: 37.545 + longitude: -122.421 + billing_phone: + country: US + is_voip: true + matches_postal: true + network_operator: Verizon/1 + number_type: fixed + credit_card: + brand: Visa + country: US + is_business: true + is_issued_in_billing_address_country: true + is_prepaid: true + is_virtual: true + issuer: + matches_provided_name: true + matches_provided_phone_number: true + name: Bank of America + phone_number: 800-732-9194 + type: credit + device: + confidence: 99 + id: 7835b099-d385-4e5b-969e-7df26181d73b + last_seen: "2016-06-08T14:16:38Z" + local_time: "2018-01-02T10:40:11-08:00" + email: + domain: + classification: business + first_seen: "2015-01-20" + risk: 1.23 + visit: + has_redirect: true + last_visited_on: "2025-11-15" + status: live + volume: 6.5 + first_seen: "2016-02-03" + is_disposable: false + is_free: false + is_high_risk: true + shipping_address: + distance_to_billing_address: 22 + distance_to_ip_location: 15 + is_high_risk: true + is_in_ip_country: true + is_postal_in_city: true + latitude: 37.632 + longitude: -122.313 + shipping_phone: + country: CA + is_voip: true + matches_postal: true + network_operator: Telus Mobility-SVR/2 + number_type: mobile + risk_score_reasons: + - multiplier: 45 + reasons: + - code: ANONYMOUS_IP + reason: The Anonymous IP address raised the overall risk score + - multiplier: 1.6 + reasons: + - code: ORG_DISTANCE_RISK + reason: >- + The risk of the ISP combined with the distance between the billing + address and IP address location raised the overall risk score + - multiplier: 0.34 + reasons: + - code: PHONE_ACTIVITY + reason: >- + minFraud network activity of the phone number lowered the overall + risk score diff --git a/examples/minfraud/insights.yaml b/examples/minfraud/insights.yaml new file mode 100644 index 0000000..2bd20b5 --- /dev/null +++ b/examples/minfraud/insights.yaml @@ -0,0 +1,205 @@ +summary: minFraud Insights response +value: + disposition: + action: accept + reason: default + rule_label: my_custom_rule + funds_remaining: 25 + id: 5bc5d6c2-b2c8-40af-87f4-6d61af86b6ae + ip_address: + risk: 0.01 + anonymizer: + confidence: 99 + is_anonymous: true + is_anonymous_vpn: true + is_hosting_provider: true + is_public_proxy: true + is_residential_proxy: true + is_tor_exit_node: true + network_last_seen: "2025-01-15" + provider_name: nordvpn + residential: + confidence: 82 + network_last_seen: "2026-05-11" + provider_name: quickshift + city: + confidence: 25 + geoname_id: 54321 + names: + de: Los Angeles + en: Los Angeles + es: Los Ángeles + fr: Los Angeles + ja: ロサンゼルス市 + pt-BR: Los Angeles + ru: Лос-Анджелес + zh-CN: 洛杉矶 + continent: + code: NA + geoname_id: 123456 + names: + de: Nordamerika + en: North America + es: América del Norte + fr: Amérique du Nord + ja: 北アメリカ + pt-BR: América do Norte + ru: Северная Америка + zh-CN: 北美洲 + country: + confidence: 75 + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + location: + accuracy_radius: 20 + average_income: 50321 + latitude: 37.6293 + local_time: "2015-04-26T01:37:17-08:00" + longitude: -122.1163 + metro_code: 807 + population_density: 7122 + time_zone: America/Los_Angeles + postal: + code: "90001" + confidence: 10 + registered_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + represented_country: + geoname_id: 6252001 + iso_code: US + names: + de: USA + en: United States + es: Estados Unidos + fr: États-Unis + ja: アメリカ合衆国 + pt-BR: Estados Unidos + ru: США + zh-CN: 美国 + type: military + risk_reasons: + - code: ANONYMOUS_IP + reason: The IP address belongs to an anonymous network. + - code: MINFRAUD_NETWORK_ACTIVITY + reason: >- + Suspicious activity has been seen on this IP address across minFraud + customers. + subdivisions: + - confidence: 50 + geoname_id: 5332921 + iso_code: CA + names: + de: Kalifornien + en: California + es: California + fr: Californie + ja: カリフォルニア + ru: Калифорния + zh-CN: 加州 + traits: + autonomous_system_number: 1239 + autonomous_system_organization: Linkem IR WiMax Network + connection_type: Cable/DSL + domain: example.com + ip_address: 1.2.3.4 + ip_risk_snapshot: 45.5 + is_anonymous: true + is_anonymous_vpn: true + is_anycast: true + is_hosting_provider: true + is_public_proxy: true + is_residential_proxy: true + is_tor_exit_node: true + isp: Linkem spa + mobile_country_code: "310" + mobile_network_code: "004" + network: 1.2.3.0/24 + organization: Linkem IR WiMax Network + static_ip_score: 1.5 + user_count: 1 + user_type: traveler + queries_remaining: 5000 + risk_score: 0.01 + warnings: + - code: INPUT_INVALID + input_pointer: /shipping/city + warning: >- + Encountered value at /shipping/city that does not meet the required + constraints + billing_address: + distance_to_ip_location: 100 + is_in_ip_country: true + is_postal_in_city: true + latitude: 37.545 + longitude: -122.421 + billing_phone: + country: US + is_voip: true + matches_postal: true + network_operator: Verizon/1 + number_type: fixed + credit_card: + brand: Visa + country: US + is_business: true + is_issued_in_billing_address_country: true + is_prepaid: true + is_virtual: true + issuer: + matches_provided_name: true + matches_provided_phone_number: true + name: Bank of America + phone_number: 800-732-9194 + type: credit + device: + confidence: 99 + id: 7835b099-d385-4e5b-969e-7df26181d73b + last_seen: "2016-06-08T14:16:38Z" + local_time: "2018-01-02T10:40:11-08:00" + email: + domain: + classification: business + first_seen: "2015-01-20" + risk: 1.23 + visit: + has_redirect: true + last_visited_on: "2025-11-15" + status: live + volume: 6.5 + first_seen: "2016-02-03" + is_disposable: false + is_free: false + is_high_risk: true + shipping_address: + distance_to_billing_address: 22 + distance_to_ip_location: 15 + is_high_risk: true + is_in_ip_country: true + is_postal_in_city: true + latitude: 37.632 + longitude: -122.313 + shipping_phone: + country: CA + is_voip: true + matches_postal: true + network_operator: Telus Mobility-SVR/2 + number_type: mobile diff --git a/examples/minfraud/report-bad-request.yaml b/examples/minfraud/report-bad-request.yaml new file mode 100644 index 0000000..eb73a00 --- /dev/null +++ b/examples/minfraud/report-bad-request.yaml @@ -0,0 +1,4 @@ +summary: Report a Transaction TAG_REQUIRED response +value: + code: TAG_REQUIRED + error: Your request does not include a tag field. diff --git a/examples/minfraud/request.yaml b/examples/minfraud/request.yaml new file mode 100644 index 0000000..faa4c49 --- /dev/null +++ b/examples/minfraud/request.yaml @@ -0,0 +1,83 @@ +summary: minFraud request body +value: + account: + user_id: "3132" + username_md5: 570a90bfbf8c7eab5dc5d4e26832d5b1 + billing: + address: 400 Blake St. + address_2: Suite 5 + city: New Haven + company: Big Corp. + country: US + first_name: John + last_name: Doe + phone_country_code: "1" + phone_number: 203-000-0000 + postal: "06511" + region: CT + credit_card: + avs_result: Y + bank_name: Bank of America + bank_phone_country_code: "1" + bank_phone_number: 800-342-1232 + country: US + cvv_result: N + issuer_id_number: "323132" + last_digits: "7643" + token: OQRST14PLQ98323 + was_3d_secure_successful: true + custom_inputs: + a_custom_input_key: NSC0083121 + another_custom_input_key: false + device: + accept_language: en-US,en;q=0.8 + ip_address: "2001:db8::ff00:42:8329" + session_age: 3600.5 + session_id: c2ffa1b7-f5c5-4702-beb2-4254794fe391 + user_agent: >- + Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) + Chrome/41.0.2272.89 Safari/537.36 + email: + address: 977577b140bfb7c516e4746204fbdb01 + domain: maxmind.com + event: + party: customer + shop_id: s2123 + transaction_id: txn3134133 + type: purchase + order: + affiliate_id: af12 + amount: 323.21 + currency: USD + discount_code: FIRST + has_gift_message: false + is_gift: true + referrer_uri: http://www.google.com/ + subaffiliate_id: saf42 + payment: + decline_code: card_declined + method: card + processor: stripe + was_authorized: false + shipping: + address: 82 Wall St. + address_2: "#1" + city: New Haven + company: Smaller, Inc. + country: US + delivery_speed: same_day + first_name: Jane + last_name: Doe + phone_country_code: "1" + phone_number: 203-000-0000 + postal: "06515" + region: CT + shopping_cart: + - category: pets + item_id: ad23232 + price: 20.43 + quantity: 2 + - category: beauty + item_id: bst112 + price: 100 + quantity: 1 diff --git a/examples/minfraud/score-bad-request.yaml b/examples/minfraud/score-bad-request.yaml new file mode 100644 index 0000000..0f6e415 --- /dev/null +++ b/examples/minfraud/score-bad-request.yaml @@ -0,0 +1,4 @@ +summary: Score REQUEST_INVALID response +value: + code: REQUEST_INVALID + error: The request did not contain any valid input values. diff --git a/examples/minfraud/score.yaml b/examples/minfraud/score.yaml new file mode 100644 index 0000000..f19623a --- /dev/null +++ b/examples/minfraud/score.yaml @@ -0,0 +1,18 @@ +summary: minFraud Score response +value: + disposition: + action: accept + reason: default + rule_label: my_custom_rule + funds_remaining: 25 + id: 5bc5d6c2-b2c8-40af-87f4-6d61af86b6ae + ip_address: + risk: 0.01 + queries_remaining: 5000 + risk_score: 0.01 + warnings: + - code: INPUT_INVALID + input_pointer: /shipping/city + warning: >- + Encountered value at /shipping/city that does not meet the required + constraints diff --git a/examples/minfraud/transaction-report.yaml b/examples/minfraud/transaction-report.yaml new file mode 100644 index 0000000..3786429 --- /dev/null +++ b/examples/minfraud/transaction-report.yaml @@ -0,0 +1,5 @@ +summary: Transaction report request +value: + ip_address: 1.2.3.4 + tag: suspected_fraud + transaction_id: "1" diff --git a/redocly.yaml b/redocly.yaml index c6d4de8..d22a53b 100644 --- a/redocly.yaml +++ b/redocly.yaml @@ -15,3 +15,6 @@ apis: geoip: root: specs/geoip.yaml output: bundled/geoip.yaml + minfraud: + root: specs/minfraud.yaml + output: bundled/minfraud.yaml diff --git a/specs/minfraud.yaml b/specs/minfraud.yaml new file mode 100644 index 0000000..7b9a053 --- /dev/null +++ b/specs/minfraud.yaml @@ -0,0 +1,601 @@ +openapi: 3.1.2 +info: + title: minFraud web services + version: 0.1.0 + summary: Fraud risk scoring for an online transaction. + description: >- + The minFraud web services score a transaction for fraud risk. Score, + Insights, and Factors accept the same request body and return increasingly + detailed risk data. Report a transaction's outcome to improve future + scoring, and read back manual disposition changes made in the account + portal. + + + MaxMind can add fields, warning codes, and enum values to a response without + a version change. Clients must ignore keys and values that they do not know. + contact: + name: MaxMind support + url: https://support.maxmind.com/ + license: + name: Apache 2.0 or MIT + identifier: Apache-2.0 OR MIT + termsOfService: https://www.maxmind.com/en/terms-of-use +externalDocs: + description: minFraud API documentation + url: https://dev.maxmind.com/minfraud/api-documentation/ +servers: + - url: https://minfraud.maxmind.com + description: minFraud web services +security: + - basicAuth: [] +tags: + - name: Score, Insights, and Factors + description: Score a transaction for fraud risk. + - name: Report a Transaction + description: Report a transaction's outcome to improve future scoring. + - name: Dispositions + description: + Read manual disposition and note changes made in the account portal. + - name: Alerts + description: >- + Receive a webhook when MaxMind re-scores a low-risk transaction as high + risk. +paths: + /minfraud/v2.0/score: + servers: + - url: https://minfraud.maxmind.com + description: minFraud web services + - url: https://sandbox.maxmind.com + description: minFraud sandbox + post: + operationId: postScore + summary: Score a transaction + description: >- + Returns the overall risk score and the risk for the IP address, but no + other risk factor data. + tags: + - Score, Insights, and Factors + externalDocs: + url: https://dev.maxmind.com/minfraud/api-documentation/responses/ + requestBody: + $ref: "#/components/requestBodies/Transaction" + responses: + "200": + description: The Score response for the transaction. + content: + application/vnd.maxmind.com-minfraud-score+json: + schema: + $ref: "../components/minfraud-response.yaml#/schemas/Score" + examples: + score: + $ref: "../examples/minfraud/score.yaml" + "400": + $ref: "#/components/responses/ScoreBadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "402": + $ref: "#/components/responses/PaymentRequired" + "403": + $ref: "#/components/responses/Forbidden" + "413": + $ref: "#/components/responses/ScorePayloadTooLarge" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalServerError" + "503": + $ref: "#/components/responses/ServiceUnavailable" + /minfraud/v2.0/insights: + servers: + - url: https://minfraud.maxmind.com + description: minFraud web services + - url: https://sandbox.maxmind.com + description: minFraud sandbox + post: + operationId: postInsights + summary: Score a transaction with IP intelligence + description: >- + Returns every field in the Score response, plus IP intelligence data + such as anonymizer detection, and risk data about the device, email, + billing address, shipping address, and credit card. + tags: + - Score, Insights, and Factors + externalDocs: + url: https://dev.maxmind.com/minfraud/api-documentation/responses/ + requestBody: + $ref: "#/components/requestBodies/Transaction" + responses: + "200": + description: The Insights response for the transaction. + content: + application/vnd.maxmind.com-minfraud-insights+json: + schema: + $ref: "../components/minfraud-response.yaml#/schemas/Insights" + examples: + insights: + $ref: "../examples/minfraud/insights.yaml" + "400": + $ref: "#/components/responses/ScoreBadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "402": + $ref: "#/components/responses/PaymentRequired" + "403": + $ref: "#/components/responses/Forbidden" + "413": + $ref: "#/components/responses/ScorePayloadTooLarge" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalServerError" + "503": + $ref: "#/components/responses/ServiceUnavailable" + /minfraud/v2.0/factors: + servers: + - url: https://minfraud.maxmind.com + description: minFraud web services + - url: https://sandbox.maxmind.com + description: minFraud sandbox + post: + operationId: postFactors + summary: Score a transaction with risk factors + description: >- + Returns every field in the Insights response, plus the risk score + reasons that explain the risk score. + tags: + - Score, Insights, and Factors + externalDocs: + url: https://dev.maxmind.com/minfraud/api-documentation/responses/ + requestBody: + $ref: "#/components/requestBodies/Transaction" + responses: + "200": + description: The Factors response for the transaction. + content: + application/vnd.maxmind.com-minfraud-factors+json: + schema: + $ref: "../components/minfraud-response.yaml#/schemas/Factors" + examples: + factors: + $ref: "../examples/minfraud/factors.yaml" + "400": + $ref: "#/components/responses/ScoreBadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "402": + $ref: "#/components/responses/PaymentRequired" + "403": + $ref: "#/components/responses/Forbidden" + "413": + $ref: "#/components/responses/ScorePayloadTooLarge" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalServerError" + "503": + $ref: "#/components/responses/ServiceUnavailable" + /minfraud/v2.0/transactions/report: + post: + operationId: reportTransaction + summary: Report a transaction's outcome + description: >- + Reports a transaction as fraud, legitimate, or another outcome, so + MaxMind can use it to improve future risk scores. Give at least one of + `ip_address`, `maxmind_id`, `minfraud_id`, and `transaction_id` in the + request body so MaxMind can match the report to the original + transaction. + tags: + - Report a Transaction + externalDocs: + url: https://dev.maxmind.com/minfraud/report-a-transaction/ + requestBody: + required: true + content: + application/json: + schema: + $ref: "../components/minfraud-request.yaml#/schemas/TransactionReport" + examples: + transactionReport: + $ref: "../examples/minfraud/transaction-report.yaml" + responses: + "204": + description: MaxMind accepted the report. + "400": + $ref: "#/components/responses/ReportBadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "403": + $ref: "#/components/responses/Forbidden" + "413": + $ref: "#/components/responses/ReportPayloadTooLarge" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalServerError" + "503": + $ref: "#/components/responses/ServiceUnavailable" + /minfraud/disposition/v1.0/updates: + get: + operationId: listDispositionUpdates + summary: List disposition and note updates + description: >- + Returns transactions whose disposition or note changed, through the + account portal's manual review, after `updates_after`. Use this only if + you set dispositions or notes from the account portal and need those + changes in your own system. + tags: + - Dispositions + externalDocs: + url: https://dev.maxmind.com/minfraud/working-with-transaction-dispositions/ + parameters: + - name: updates_after + in: query + required: true + description: >- + An exclusive lower bound, as an RFC 3339 timestamp. MaxMind returns + only updates made after this time. URL-encode the value, for example + send a `+` in the UTC offset as `%2B`. Pass the previous response's + `last_update_timestamp` to page through results. + schema: + type: string + format: date-time + responses: + "200": + description: The transactions with a disposition or note update. + content: + application/vnd.maxmind.com-disposition-updates+json: + schema: + $ref: "../components/minfraud-response.yaml#/schemas/DispositionUpdatesResponse" + examples: + dispositionUpdates: + $ref: "../examples/minfraud/disposition-updates.yaml" + "400": + $ref: "#/components/responses/DispositionBadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "403": + $ref: "#/components/responses/Forbidden" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalServerError" + "503": + $ref: "#/components/responses/ServiceUnavailable" +webhooks: + minFraudAlert: + get: + operationId: minFraudAlert + security: [] + summary: Receive a minFraud Alert + description: >- + MaxMind monitors a transaction for 24 hours after it first scores 10 or + below. If new information raises the re-calculated risk score to 75 or + above, MaxMind sends this request to the webhook URL you configure in + the account portal. Your endpoint must accept `GET` requests over HTTPS. + + + MaxMind can add query parameters. Ignore parameters you do not know. + Requests come from `34.27.174.58` or `2600:1900:4000:947::/64`. These + source addresses can change. + tags: + - Alerts + externalDocs: + url: https://dev.maxmind.com/minfraud/alerts/ + parameters: + - name: User-Agent + in: header + required: false + description: The value is `MaxMind MinFraud Alert Robot`. + schema: + type: string + - name: X-MaxMind-Alert-HMAC-SHA256 + in: header + required: false + description: >- + The hex-encoded HMAC-SHA256 signature of the raw query string, using + the webhook secret you configure in the account portal. Present only + when you configure a secret. + schema: + type: string + - name: city + in: query + required: false + description: The billing city from the original minFraud request. + schema: + type: string + maxLength: 255 + - name: country + in: query + required: false + description: The billing country from the original minFraud request. + schema: + type: string + maxLength: 2 + - name: date + in: query + required: false + description: >- + The date of the original minFraud request, for example `Nov. 1, + 2019`. + schema: + type: string + maxLength: 255 + - name: domain + in: query + required: false + description: The email domain from the original minFraud request. + schema: + type: string + maxLength: 255 + - name: i + in: query + required: false + description: The IP address from the original minFraud request. + schema: + type: string + anyOf: + - format: ipv4 + - format: ipv6 + - maxLength: 0 + - name: maxmindID + in: query + required: false + description: The minFraud Legacy `maxmindID` of the original request. + schema: + type: string + maxLength: 8 + - name: minfraud_id + in: query + required: false + description: The minFraud ID of the original request. + schema: + type: string + format: uuid + - name: new_risk_score + in: query + required: false + description: + The risk score MaxMind recalculated with additional information. + schema: + type: number + minimum: 0.01 + maximum: 99 + - name: old_risk_score + in: query + required: false + description: The risk score as originally calculated. + schema: + type: number + minimum: 0.01 + maximum: 99 + - name: postal + in: query + required: false + description: + The billing postal code from the original minFraud request. + schema: + type: string + maxLength: 255 + - name: reason + in: query + required: false + description: + A human-readable explanation of why MaxMind sent the alert. + schema: + type: string + - name: reason_code + in: query + required: false + description: >- + A machine-readable code for why MaxMind sent the alert. Known + values: `CARDER_EMAIL`, `HIGH_RISK_DEVICE`, `HIGH_RISK_IP`, + `HOSTING_PROVIDER`, `MANUAL_REVIEW`, `POSTAL_VELOCITY`. These values + can change. + schema: + type: string + - name: region + in: query + required: false + description: The billing region from the original minFraud request. + schema: + type: string + maxLength: 4 + - name: shop_id + in: query + required: false + description: >- + The shop ID from the original minFraud request. Present only when + the original request gave one. + schema: + type: string + maxLength: 255 + - name: txnID + in: query + required: false + description: The transaction ID from the original minFraud request. + schema: + type: string + maxLength: 255 + - name: updated_at + in: query + required: false + description: >- + The date and time the new risk score was calculated, in RFC 3339 + format, for example `2019-11-01T12:34:56Z`. + schema: + type: string + format: date-time + responses: + "2XX": + description: Return a 2xx status to acknowledge the alert. +components: + securitySchemes: + basicAuth: + type: http + scheme: basic + description: >- + The username is your MaxMind account ID. The password is your MaxMind + license key. The service accepts HTTPS requests only, with TLS 1.2 or + higher. + requestBodies: + Transaction: + description: The request body must not exceed 20,000 bytes. + required: true + content: + application/json: + schema: + $ref: "../components/minfraud-request.yaml#/schemas/Request" + examples: + request: + $ref: "../examples/minfraud/request.yaml" + responses: + ScoreBadRequest: + description: >- + The request is not valid. The `code` is one of: + + - `JSON_INVALID`: the request body is not a JSON object. + + - `REQUEST_INVALID`: the request body is valid JSON but has no valid + input values. + + - `REQUEST_TOO_BIG`: the request body is too large. + + - `BAD_REQUEST`: there was a problem reading or decoding the request + body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + examples: + error: + $ref: "../examples/minfraud/score-bad-request.yaml" + ReportBadRequest: + description: >- + The request is not valid. The `code` is one of: + + - `JSON_INVALID`: the request body is not a valid JSON object. + + - `PARAMETER_UNKNOWN`: the request has a key this endpoint does not use. + + - `TAG_REQUIRED`: the request has no `tag`. + + - `TAG_INVALID`: `tag` is not one of the accepted values. + + - `TRANSACTION_ID_REQUIRED`: the request has none of `ip_address`, + `maxmind_id`, `minfraud_id`, and `transaction_id`. + + - `IP_ADDRESS_INVALID`: `ip_address` is not a valid IPv4 or IPv6 + address. + + - `IP_ADDRESS_RESERVED`: `ip_address` is in a reserved or private range. + + - `MAXMIND_ID_INVALID`: `maxmind_id` is not a valid MaxMind ID. It must + be 8 characters of digits and uppercase letters. + + - `MINFRAUD_ID_INVALID`: `minfraud_id` is not a valid UUID. + + - `NOTES_INVALID`: `notes` is over 1000 Unicode characters or contains a + NUL character. + + - Other `_INVALID` codes, for example `TRANSACTION_ID_INVALID`: the + value of that field is not valid. `TRANSACTION_ID_INVALID` and + `CHARGEBACK_CODE_INVALID` also cover a field that contains a NUL + character. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + examples: + error: + $ref: "../examples/minfraud/report-bad-request.yaml" + DispositionBadRequest: + description: >- + The request is not valid. The `code` is one of: + + - `UPDATES_AFTER_REQUIRED`: the request has no `updates_after` + parameter, or its value is empty. + + - `TIMESTAMP_INVALID`: `updates_after` is not a valid RFC 3339 + timestamp. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + examples: + error: + $ref: "../examples/minfraud/disposition-bad-request.yaml" + Unauthorized: + description: >- + The credentials are missing or not valid. The `code` is one of: + + - `AUTHORIZATION_INVALID`: the account ID or license key is not valid. + + - `ACCOUNT_ID_REQUIRED`: the Basic credentials have no account ID. + + - `LICENSE_KEY_REQUIRED`: the Basic credentials have no license key. + headers: + WWW-Authenticate: + description: >- + The authentication scheme, for example `Basic realm="minfraud"`. + schema: + type: string + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + examples: + error: + value: + code: AUTHORIZATION_INVALID + error: + Your account ID or license key could not be authenticated. + PaymentRequired: + description: + The account has no funds for this service (`INSUFFICIENT_FUNDS`). + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + examples: + error: + $ref: "../examples/minfraud/error.yaml" + Forbidden: + description: >- + The account does not have permission to use this service + (`PERMISSION_REQUIRED`). A request that uses HTTP instead of HTTPS also + gets this status, but without a JSON body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + examples: + error: + value: + code: PERMISSION_REQUIRED + error: You do not have permission to use the service. + ScorePayloadTooLarge: + description: >- + The request body is larger than 20,000 bytes. The response does not have + a JSON body. + ReportPayloadTooLarge: + description: >- + The request body is too large. The response does not have a JSON body. + TooManyRequests: + description: >- + MaxMind rate-limited the request, usually because of too many earlier + error responses. The response may have no body. + InternalServerError: + description: The service had an unexpected error (`SERVER_ERROR`). + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + examples: + error: + value: + code: SERVER_ERROR + error: There was an error when processing this request. + ServiceUnavailable: + description: >- + The service has a temporary problem. Send the request again later. The + response does not have a JSON body. From 4c64034bfe78e3141c4deced2ebb93f6e2759712 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Tue, 22 Sep 2026 18:35:17 +0000 Subject: [PATCH 03/31] Add account and download API specs Describe the Privacy Exclusions API, the License Key Validation API, and the database and geofeed report downloads in OpenAPI 3.1. A successful download is a redirect, so Redocly's rule that requires a 2xx response is off for the downloads spec only. Co-Authored-By: Claude Opus 5.5 (1M context) --- CHANGELOG.md | 1 + README.md | 11 +- bundled/downloads.yaml | 358 ++++++++++++++++ bundled/license-key-validation.yaml | 130 ++++++ bundled/privacy-exclusions.yaml | 188 +++++++++ examples/privacy-exclusions/exclusions.yaml | 7 + redocly.yaml | 12 + specs/downloads.yaml | 446 ++++++++++++++++++++ specs/license-key-validation.yaml | 139 ++++++ specs/privacy-exclusions.yaml | 204 +++++++++ 10 files changed, 1492 insertions(+), 4 deletions(-) create mode 100644 bundled/downloads.yaml create mode 100644 bundled/license-key-validation.yaml create mode 100644 bundled/privacy-exclusions.yaml create mode 100644 examples/privacy-exclusions/exclusions.yaml create mode 100644 specs/downloads.yaml create mode 100644 specs/license-key-validation.yaml create mode 100644 specs/privacy-exclusions.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 97c836b..1b77ab4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,3 +4,4 @@ - Add the GeoIP and GeoLite web services spec. - Add the minFraud web services spec. +- Add the Privacy Exclusions, License Key Validation, and download specs. diff --git a/README.md b/README.md index 061534f..3254a7d 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,13 @@ This repository holds [OpenAPI 3.1](https://spec.openapis.org/oas/v3.1.2) descriptions of the MaxMind public web services. -| Product | Bundled spec | Documentation | -| ------------------------------ | ------------------------------------------------ | ---------------------------------------------------------------------- | -| GeoIP and GeoLite web services | [`bundled/geoip.yaml`](bundled/geoip.yaml) | [dev.maxmind.com](https://dev.maxmind.com/geoip/docs/web-services/) | -| minFraud web services | [`bundled/minfraud.yaml`](bundled/minfraud.yaml) | [dev.maxmind.com](https://dev.maxmind.com/minfraud/api-documentation/) | +| Product | Bundled spec | Documentation | +| ------------------------------ | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------ | +| GeoIP and GeoLite web services | [`bundled/geoip.yaml`](bundled/geoip.yaml) | [dev.maxmind.com](https://dev.maxmind.com/geoip/docs/web-services/) | +| minFraud web services | [`bundled/minfraud.yaml`](bundled/minfraud.yaml) | [dev.maxmind.com](https://dev.maxmind.com/minfraud/api-documentation/) | +| Privacy exclusions | [`bundled/privacy-exclusions.yaml`](bundled/privacy-exclusions.yaml) | [dev.maxmind.com](https://dev.maxmind.com/geoip/privacy-exclusions-api/) | +| License key validation | [`bundled/license-key-validation.yaml`](bundled/license-key-validation.yaml) | [dev.maxmind.com](https://dev.maxmind.com/license-key-validation-api/) | +| Database and geofeed downloads | [`bundled/downloads.yaml`](bundled/downloads.yaml) | [dev.maxmind.com](https://dev.maxmind.com/geoip/updating-databases/) | Each file in `bundled/` is self-contained. Use it with API tools and code generators. The files in `specs/`, `components/`, and `examples/` are the diff --git a/bundled/downloads.yaml b/bundled/downloads.yaml new file mode 100644 index 0000000..d8088c5 --- /dev/null +++ b/bundled/downloads.yaml @@ -0,0 +1,358 @@ +openapi: 3.1.2 +info: + title: Database and geofeed report downloads + version: 0.1.0 + summary: Download GeoIP and GeoLite database files and GeoIP Exchange geofeed reports. + description: |- + This API lets an authorized MaxMind account download GeoIP and GeoLite database files, and download GeoIP Exchange geofeed reports. A successful `GET` request, or a `HEAD` request for a geofeed report, redirects to a signed URL for the file, so a client must follow redirects. + + A geofeed error response with the `code` field has the `Content-Type` header `application/vnd.maxmind.com-error+json; charset=UTF-8; version=2.0`. Clients must handle any 4xx or 5xx status and check `Content-Type` before they decode an error body. + + MaxMind reserves the right to limit the number of downloads made within a period of time. See [Download and update MaxMind databases](https://support.maxmind.com/knowledge-base/articles/download-and-update-maxmind-databases). MaxMind may also rate-limit an account that sends excessive unsuccessful requests, for example requests with bad credentials or a lapsed subscription. + contact: + name: MaxMind support + url: https://support.maxmind.com/ + license: + name: Apache 2.0 or MIT + identifier: Apache-2.0 OR MIT + termsOfService: https://www.maxmind.com/en/terms-of-use +servers: + - url: https://download.maxmind.com + description: Database and geofeed report downloads +security: + - basicAuth: [] +tags: + - name: Database downloads + description: Download GeoIP and GeoLite database files. + - name: Geofeed reports + description: Download GeoIP Exchange geofeed reports. +externalDocs: + description: Updating GeoIP and GeoLite databases documentation + url: https://dev.maxmind.com/geoip/updating-databases/ +paths: + /geoip/databases/{edition_id}/download: + parameters: + - $ref: '#/components/parameters/EditionID' + - $ref: '#/components/parameters/Suffix' + - $ref: '#/components/parameters/Date' + - $ref: '#/components/parameters/ArtifactType' + get: + operationId: downloadDatabase + summary: Download a database file + description: Redirects to a signed URL for the database file. Each database download counts against the account's download limit for a 24-hour period. + tags: + - Database downloads + externalDocs: + description: Updating GeoIP and GeoLite databases documentation + url: https://dev.maxmind.com/geoip/updating-databases/ + responses: + '302': + description: Redirects to a signed URL for the file. The response has no body. The file name is `_[_].`. + headers: + Location: + description: The signed URL for the file, on the host `mm-prod-geoip-databases.a2649acb697e2c09b632799562c076f2.r2.cloudflarestorage.com`. Firewalls and proxies must allow HTTPS connections to this host. + schema: + type: string + '400': + $ref: '#/components/responses/DownloadBadRequest' + '401': + $ref: '#/components/responses/DownloadUnauthorized' + '403': + $ref: '#/components/responses/DownloadForbidden' + '404': + $ref: '#/components/responses/DownloadNotFound' + '429': + $ref: '#/components/responses/DownloadTooManyRequests' + '451': + $ref: '#/components/responses/DownloadLegalReasons' + '500': + $ref: '#/components/responses/DownloadInternalServerError' + '503': + $ref: '#/components/responses/DownloadServiceUnavailable' + head: + operationId: checkDatabaseBuildDate + summary: Check a database file's build date + description: Returns the headers for the database file without its body. Use this to check the `Last-Modified` build date before downloading. A HEAD request does not count against the account's download limit. + tags: + - Database downloads + externalDocs: + description: Updating GeoIP and GeoLite databases documentation + url: https://dev.maxmind.com/geoip/updating-databases/ + responses: + '200': + description: The headers for the file. The response has no body. + headers: + Last-Modified: + description: The build date of the file. + schema: + type: string + Content-Disposition: + description: '`attachment`, with a `filename` of `_[_].`.' + schema: + type: string + Content-Type: + description: The media type for the `suffix` requested. + schema: + type: string + '400': + $ref: '#/components/responses/DownloadBadRequest' + '401': + $ref: '#/components/responses/DownloadUnauthorized' + '403': + $ref: '#/components/responses/DownloadForbidden' + '404': + $ref: '#/components/responses/DownloadNotFound' + '429': + $ref: '#/components/responses/DownloadTooManyRequests' + '451': + $ref: '#/components/responses/DownloadLegalReasons' + '500': + $ref: '#/components/responses/DownloadInternalServerError' + '503': + $ref: '#/components/responses/DownloadServiceUnavailable' + /geofeed/reports/v1.0/{geofeed_id}/{report_id}: + parameters: + - $ref: '#/components/parameters/GeofeedID' + - $ref: '#/components/parameters/ReportID' + get: + operationId: downloadGeofeedReport + summary: Download a geofeed report + description: Redirects to a signed URL for a GeoIP Exchange geofeed report. + tags: + - Geofeed reports + externalDocs: + description: GeoIP Exchange documentation + url: https://dev.maxmind.com/geoip/geoip-exchange/ + responses: + '307': + description: Redirects to a signed URL for the report. The file is `.csv`. + headers: + Location: + description: The signed URL for the report, on the host `storage.googleapis.com`. + schema: + type: string + '400': + $ref: '#/components/responses/GeofeedBadRequest' + '401': + $ref: '#/components/responses/GeofeedUnauthorized' + '403': + $ref: '#/components/responses/GeofeedForbidden' + '404': + $ref: '#/components/responses/GeofeedNotFound' + '500': + $ref: '#/components/responses/GeofeedInternalServerError' + '503': + $ref: '#/components/responses/GeofeedServiceUnavailable' + head: + operationId: checkGeofeedReportBuildDate + summary: Check a geofeed report's build date + description: Redirects to a signed URL for a GeoIP Exchange geofeed report, the same as `GET`, but without a response body. Follow the redirect with HEAD. The storage host's response has the `Last-Modified` build date, not this 307 response. + tags: + - Geofeed reports + externalDocs: + description: GeoIP Exchange documentation + url: https://dev.maxmind.com/geoip/geoip-exchange/ + responses: + '307': + description: Redirects to a signed URL for the report. The response has no body. The file is `.csv`. + headers: + Location: + description: The signed URL for the report, on the host `storage.googleapis.com`. + schema: + type: string + '400': + $ref: '#/components/responses/GeofeedBadRequest' + '401': + $ref: '#/components/responses/GeofeedUnauthorized' + '403': + $ref: '#/components/responses/GeofeedForbidden' + '404': + $ref: '#/components/responses/GeofeedNotFound' + '500': + $ref: '#/components/responses/GeofeedInternalServerError' + '503': + $ref: '#/components/responses/GeofeedServiceUnavailable' +components: + securitySchemes: + basicAuth: + type: http + scheme: basic + description: The username is your MaxMind account ID. The password is your MaxMind license key. The service accepts HTTPS requests only. + parameters: + EditionID: + name: edition_id + in: path + required: true + description: The edition ID of the database. Edition IDs are case sensitive. An ID with the wrong case returns 404. + schema: + type: string + pattern: ^[A-Za-z0-9_-]+$ + examples: + city: + value: GeoIP2-City + cityCSV: + value: GeoIP2-City-CSV + Suffix: + name: suffix + in: query + required: true + description: The file format to download. Binary editions use `tar.gz` and CSV editions use `zip`. `csv` with `artifact_type` downloads a report for either the binary or the CSV edition, for example the [location name diff report](https://dev.maxmind.com/geoip/track-location-name-updates/). `tar.gz.md5`, `tar.gz.sha256`, `zip.md5`, and `zip.sha256` download a checksum file for the matching archive instead of the archive itself. + schema: + type: string + enum: + - tar.gz + - zip + - csv + - tar.gz.md5 + - tar.gz.sha256 + - zip.md5 + - zip.sha256 + examples: + tarGz: + value: tar.gz + zip: + value: zip + csv: + value: csv + Date: + name: date + in: query + required: false + description: Restricts the download to the release built on this date, in `YYYYMMDD` format. If not present, MaxMind returns the latest release. + schema: + type: string + pattern: ^[0-9]{8}$ + examples: + date: + value: '20200121' + ArtifactType: + name: artifact_type + in: query + required: false + description: 'The kind of artifact to download instead of the database file itself. Known value: `Locations-Diff-Report`, paired with `suffix=csv`, for the [location name diff report](https://dev.maxmind.com/geoip/track-location-name-updates/). MaxMind may add other values.' + schema: + type: string + examples: + locationsDiffReport: + value: Locations-Diff-Report + GeofeedID: + name: geofeed_id + in: path + required: true + description: The numeric ID for the geofeed, from the GeoIP Exchange section of your account portal. + schema: + type: integer + minimum: 1 + examples: + geofeedID: + value: 12345 + ReportID: + name: report_id + in: path + required: true + description: The kind of geofeed report to download. + schema: + type: string + enum: + - free + - geolocation + - intelligence + examples: + geolocation: + value: geolocation + responses: + DownloadBadRequest: + description: The request is not valid. The response does not have a JSON body, for example `Invalid edition ID`, `Invalid suffix`, `Invalid date`, `"" is an invalid date`, or `"" is an invalid artifact type`. + DownloadUnauthorized: + description: The credentials are missing or not valid. The response does not have a JSON body, for example `An account ID and license key are required to use this service.` or `Your account ID or license key could not be authenticated.` + headers: + WWW-Authenticate: + description: The authentication scheme, `Basic realm="geoip-download"`. + schema: + type: string + DownloadForbidden: + description: The account cannot use this download service, or has no active subscription for this database edition (free editions need no subscription). The response does not have a JSON body, for example `You do not have permission to use this service interface.` or `Invalid product ID or subscription expired for `. + DownloadNotFound: + description: No file matches the edition ID, date, and suffix, or the path does not match a download URL. The response does not have a JSON body, for example `Database edition "" not found`. + DownloadTooManyRequests: + description: The account reached its download limit for a 24-hour period. The response does not have a JSON body. + DownloadLegalReasons: + description: MaxMind cannot provide this download for legal reasons. The response does not have a JSON body, for example `Downloads are forbidden from countries and territories on the US embargo list` or `Downloads of this database from are forbidden due to US bulk sensitive data transfer rules`. + DownloadInternalServerError: + description: The service had an unexpected error. The response does not have a JSON body. + DownloadServiceUnavailable: + description: The service has a temporary problem. Send the request again later. The response does not have a JSON body, for example `Unable to reach the GeoIP download service. Please try again later.` + GeofeedBadRequest: + description: The geofeed ID in the path is not a valid integer (`GEOFEED_ID_INVALID`). + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + example: + code: GEOFEED_ID_INVALID + error: '''abc'' is not a valid geofeed_id.' + GeofeedForbidden: + description: The account does not have permission to download this kind of report (`PERMISSION_REQUIRED`). A request that uses HTTP instead of HTTPS also gets this status, but without a JSON body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + example: + code: PERMISSION_REQUIRED + error: You do not have permission to use the service. + GeofeedUnauthorized: + description: |- + The credentials are missing or not valid. The `code` is one of: + - `AUTHORIZATION_INVALID`: the account ID or license key is not valid. + - `ACCOUNT_ID_REQUIRED`: the Basic credentials have no account ID. + - `LICENSE_KEY_REQUIRED`: the Basic credentials have no license key. + headers: + WWW-Authenticate: + description: The authentication scheme, `Basic realm="geofeed-report"`. + schema: + type: string + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + example: + code: ACCOUNT_ID_REQUIRED + error: An account ID and license key are required to use this service. + GeofeedNotFound: + description: No report matches the geofeed ID and report kind, or the geofeed belongs to a different account (`REPORT_NOT_FOUND`). Some 404 responses do not have a JSON body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + example: + code: REPORT_NOT_FOUND + error: Report not found with the given date. + GeofeedInternalServerError: + description: The service had an unexpected error (`SERVER_ERROR`). + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + example: + code: SERVER_ERROR + error: There was an error when processing this request. + GeofeedServiceUnavailable: + description: The service has a temporary problem. Send the request again later. The response does not have a JSON body. + schemas: + Error: + type: object + description: Not all error responses have a JSON body. Check the `Content-Type` header before you decode the body as JSON. + required: + - code + - error + properties: + code: + type: string + description: A static error code for machine use. The meaning of a code never changes, but MaxMind can add or remove codes. + examples: + - IP_ADDRESS_INVALID + error: + type: string + description: A human-readable description of the error. The text can change at any time. + examples: + - The value '1.2.3' is not a valid IP address. diff --git a/bundled/license-key-validation.yaml b/bundled/license-key-validation.yaml new file mode 100644 index 0000000..c68b841 --- /dev/null +++ b/bundled/license-key-validation.yaml @@ -0,0 +1,130 @@ +openapi: 3.1.2 +info: + title: License Key Validation API + version: 0.1.0 + summary: Check whether a license key has a valid format and is known to MaxMind. + description: |- + The License Key Validation API checks whether a license key has a valid format and whether MaxMind knows the key. It does not check what products or services the license key can access, or return the account that owns the key. Use this API to scan your own code and configuration for secrets, so that license keys do not end up in places you did not intend. + + Clients must handle any 4xx or 5xx status and check `Content-Type` before they decode an error body. + contact: + name: MaxMind support + url: https://support.maxmind.com/ + license: + name: Apache 2.0 or MIT + identifier: Apache-2.0 OR MIT + termsOfService: https://www.maxmind.com/en/terms-of-use +servers: + - url: https://secret-scanning.maxmind.com + description: License key validation +tags: + - name: License key validation + description: Check a license key's format and validity. +externalDocs: + description: License Key Validation API documentation + url: https://dev.maxmind.com/license-key-validation-api/ +paths: + /secrets/validate-license-key: + post: + operationId: validateLicenseKey + summary: Validate a license key + description: Checks whether a license key has a valid format and is known to MaxMind. The request carries the license key to validate, so it needs no other authorization. + tags: + - License key validation + security: [] + externalDocs: + description: License Key Validation API documentation + url: https://dev.maxmind.com/license-key-validation-api/ + requestBody: + description: The request body must use `application/x-www-form-urlencoded`. + required: true + content: + application/x-www-form-urlencoded: + schema: + type: object + required: + - license_key + properties: + license_key: + type: string + description: The license key to validate. + examples: + validate: + summary: A license key to validate + value: + license_key: your_license_key_here + responses: + '204': + description: The license key has a valid format and MaxMind knows it. + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '413': + $ref: '#/components/responses/PayloadTooLarge' + '500': + $ref: '#/components/responses/InternalServerError' + '503': + $ref: '#/components/responses/ServiceUnavailable' +components: + responses: + BadRequest: + description: The request is not valid (`LICENSE_KEY_INVALID`). This happens when the `license_key` field is missing, empty, or not in the format of a MaxMind license key. + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + code: LICENSE_KEY_INVALID + error: '''foo-bad-license-key'' is not a valid license_key when calling /secrets/validate-license-key.' + Unauthorized: + description: The license key has a valid format, but MaxMind does not know it (`AUTHORIZATION_INVALID`). + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + code: AUTHORIZATION_INVALID + error: Your account ID or license key could not be authenticated. + Forbidden: + description: The account that owns the license key does not have permission to use this service (`PERMISSION_REQUIRED`). This response means that MaxMind recognizes the key. An unknown key gets a 401 response instead. A request that uses HTTP instead of HTTPS also gets this status, but without a JSON body. + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + code: PERMISSION_REQUIRED + error: You do not have permission to use this service interface. + PayloadTooLarge: + description: The request body is too large. The response does not have a JSON body. + InternalServerError: + description: The service had an unexpected error (`SERVER_ERROR`). + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + code: SERVER_ERROR + error: There was an error when processing this request. + ServiceUnavailable: + description: The service has a temporary problem. Send the request again later. The response does not have a JSON body. + schemas: + Error: + type: object + description: Not all error responses have a JSON body. Check the `Content-Type` header before you decode the body as JSON. + required: + - code + - error + properties: + code: + type: string + description: A static error code for machine use. The meaning of a code never changes, but MaxMind can add or remove codes. + examples: + - IP_ADDRESS_INVALID + error: + type: string + description: A human-readable description of the error. The text can change at any time. + examples: + - The value '1.2.3' is not a valid IP address. diff --git a/bundled/privacy-exclusions.yaml b/bundled/privacy-exclusions.yaml new file mode 100644 index 0000000..93d57bb --- /dev/null +++ b/bundled/privacy-exclusions.yaml @@ -0,0 +1,188 @@ +openapi: 3.1.2 +info: + title: Privacy Exclusions API + version: 0.1.0 + summary: Retrieve Do Not Sell My Personal Information exclusion requests. + description: |- + The Privacy Exclusions API returns the networks that MaxMind excludes from its services under Do Not Sell My Personal Information requests, such as those made under the California Consumer Privacy Act (CCPA). + + A successful response has the `Content-Type` header `application/vnd.maxmind.com-privacy-exclusions+json; charset=UTF-8; version=1.0`. An error response has `application/vnd.maxmind.com-error+json; charset=UTF-8; version=2.0`. + + Clients must handle any 4xx or 5xx status and check `Content-Type` before they decode an error body. + contact: + name: MaxMind support + url: https://support.maxmind.com/ + license: + name: Apache 2.0 or MIT + identifier: Apache-2.0 OR MIT + termsOfService: https://www.maxmind.com/en/terms-of-use +servers: + - url: https://api.maxmind.com + description: MaxMind web services +security: + - basicAuth: [] +tags: + - name: Privacy exclusions + description: Privacy exclusion requests. +externalDocs: + description: Privacy Exclusions API documentation + url: https://dev.maxmind.com/geoip/privacy-exclusions-api/ +paths: + /privacy/exclusions: + get: + operationId: getPrivacyExclusions + summary: List privacy exclusions + description: Returns the current Do Not Sell My Personal Information exclusions. Each exclusion is a network that MaxMind excludes from its services. The response always includes a `Content-Length` header. + tags: + - Privacy exclusions + externalDocs: + description: Privacy Exclusions API documentation + url: https://dev.maxmind.com/geoip/privacy-exclusions-api/ + parameters: + - $ref: '#/components/parameters/UpdatesAfter' + responses: + '200': + description: The current privacy exclusions. + content: + application/vnd.maxmind.com-privacy-exclusions+json: + schema: + $ref: '#/components/schemas/ExclusionsResponse' + examples: + exclusions: + $ref: '#/components/examples/exclusions' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '500': + $ref: '#/components/responses/InternalServerError' + '503': + $ref: '#/components/responses/ServiceUnavailable' +components: + securitySchemes: + basicAuth: + type: http + scheme: basic + description: The username is your MaxMind account ID. The password is your MaxMind license key. The service accepts HTTPS requests only, with TLS 1.2 or higher. The authorization realm is `privacy-exclusion`. + parameters: + UpdatesAfter: + name: updates_after + in: query + required: false + description: If present, the response includes only exclusions updated after this time. The value is an RFC 3339 timestamp. URL-encode the value, for example send a `+` in the UTC offset as `%2B`. + schema: + type: string + format: date-time + examples: + updatesAfter: + value: '2020-04-12T23:20:50.52Z' + schemas: + Exclusion: + type: object + description: A single privacy exclusion request. MaxMind can add keys in the future. + required: + - exclusion_type + - data_type + - value + - last_updated + properties: + exclusion_type: + type: string + description: The governing law or rule for the exclusion. Currently the only value is `ccpa_do_not_sell`, for a request made under the California Consumer Privacy Act. + data_type: + type: string + description: 'The type of the `value` field. Known value: `network`, an IP network in CIDR notation. All IP addresses in the network are excluded. Check this field before you use the associated `value`. MaxMind may add other values.' + value: + type: string + description: The excluded value, in the format the `data_type` field gives. + last_updated: + type: string + format: date-time + description: The RFC 3339 timestamp of the last update to the exclusion. + ExclusionsResponse: + type: object + description: The Privacy Exclusions response. MaxMind can add keys in the future. + required: + - exclusions + properties: + exclusions: + type: array + description: The current privacy exclusions. Empty if there are none. + items: + $ref: '#/components/schemas/Exclusion' + Error: + type: object + description: Not all error responses have a JSON body. Check the `Content-Type` header before you decode the body as JSON. + required: + - code + - error + properties: + code: + type: string + description: A static error code for machine use. The meaning of a code never changes, but MaxMind can add or remove codes. + examples: + - IP_ADDRESS_INVALID + error: + type: string + description: A human-readable description of the error. The text can change at any time. + examples: + - The value '1.2.3' is not a valid IP address. + responses: + BadRequest: + description: The request is not valid (`TIMESTAMP_INVALID`). The `updates_after` value is not a valid RFC 3339 timestamp. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + example: + code: TIMESTAMP_INVALID + error: The updates_after field must be in RFC 3339 format. + Unauthorized: + description: |- + The credentials are missing or not valid. The `code` is one of: + - `AUTHORIZATION_INVALID`: the account ID or license key is not valid. + - `ACCOUNT_ID_REQUIRED`: the Basic credentials have no account ID. + - `LICENSE_KEY_REQUIRED`: the Basic credentials have no license key. + headers: + WWW-Authenticate: + description: The authentication scheme, `Basic realm="privacy-exclusion"`. + schema: + type: string + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + example: + code: ACCOUNT_ID_REQUIRED + error: An account ID and license key are required to use this service. + Forbidden: + description: The account does not have permission to use this service (`PERMISSION_REQUIRED`). A request that uses HTTP instead of HTTPS also gets this status, but without a JSON body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + example: + code: PERMISSION_REQUIRED + error: You do not have permission to use the service. + InternalServerError: + description: The service had an unexpected error (`SERVER_ERROR`). + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: '#/components/schemas/Error' + example: + code: SERVER_ERROR + error: There was an error when processing this request. + ServiceUnavailable: + description: The service has a temporary problem. Check https://status.maxmind.com, or send the request again later. The response does not have a JSON body. + examples: + exclusions: + summary: Privacy exclusions response + value: + exclusions: + - exclusion_type: ccpa_do_not_sell + data_type: network + value: 10.0.26.166/32 + last_updated: '2020-01-08T18:58:38Z' diff --git a/examples/privacy-exclusions/exclusions.yaml b/examples/privacy-exclusions/exclusions.yaml new file mode 100644 index 0000000..d399acc --- /dev/null +++ b/examples/privacy-exclusions/exclusions.yaml @@ -0,0 +1,7 @@ +summary: Privacy exclusions response +value: + exclusions: + - exclusion_type: ccpa_do_not_sell + data_type: network + value: 10.0.26.166/32 + last_updated: "2020-01-08T18:58:38Z" diff --git a/redocly.yaml b/redocly.yaml index d22a53b..a08ed18 100644 --- a/redocly.yaml +++ b/redocly.yaml @@ -18,3 +18,15 @@ apis: minfraud: root: specs/minfraud.yaml output: bundled/minfraud.yaml + privacy-exclusions: + root: specs/privacy-exclusions.yaml + output: bundled/privacy-exclusions.yaml + license-key-validation: + root: specs/license-key-validation.yaml + output: bundled/license-key-validation.yaml + downloads: + root: specs/downloads.yaml + output: bundled/downloads.yaml + rules: + # A successful download is a redirect (302/307), not a 2xx response. + operation-2xx-response: off diff --git a/specs/downloads.yaml b/specs/downloads.yaml new file mode 100644 index 0000000..3328677 --- /dev/null +++ b/specs/downloads.yaml @@ -0,0 +1,446 @@ +openapi: 3.1.2 +info: + title: Database and geofeed report downloads + version: 0.1.0 + summary: + Download GeoIP and GeoLite database files and GeoIP Exchange geofeed + reports. + description: >- + This API lets an authorized MaxMind account download GeoIP and GeoLite + database files, and download GeoIP Exchange geofeed reports. A successful + `GET` request, or a `HEAD` request for a geofeed report, redirects to a + signed URL for the file, so a client must follow redirects. + + + A geofeed error response with the `code` field has the `Content-Type` header + `application/vnd.maxmind.com-error+json; charset=UTF-8; version=2.0`. + Clients must handle any 4xx or 5xx status and check `Content-Type` before + they decode an error body. + + + MaxMind reserves the right to limit the number of downloads made within a + period of time. See [Download and update MaxMind + databases](https://support.maxmind.com/knowledge-base/articles/download-and-update-maxmind-databases). + MaxMind may also rate-limit an account that sends excessive unsuccessful + requests, for example requests with bad credentials or a lapsed + subscription. + contact: + name: MaxMind support + url: https://support.maxmind.com/ + license: + name: Apache 2.0 or MIT + identifier: Apache-2.0 OR MIT + termsOfService: https://www.maxmind.com/en/terms-of-use +externalDocs: + description: Updating GeoIP and GeoLite databases documentation + url: https://dev.maxmind.com/geoip/updating-databases/ +servers: + - url: https://download.maxmind.com + description: Database and geofeed report downloads +security: + - basicAuth: [] +tags: + - name: Database downloads + description: Download GeoIP and GeoLite database files. + - name: Geofeed reports + description: Download GeoIP Exchange geofeed reports. +paths: + /geoip/databases/{edition_id}/download: + parameters: + - $ref: "#/components/parameters/EditionID" + - $ref: "#/components/parameters/Suffix" + - $ref: "#/components/parameters/Date" + - $ref: "#/components/parameters/ArtifactType" + get: + operationId: downloadDatabase + summary: Download a database file + description: >- + Redirects to a signed URL for the database file. Each database download + counts against the account's download limit for a 24-hour period. + tags: + - Database downloads + externalDocs: + description: Updating GeoIP and GeoLite databases documentation + url: https://dev.maxmind.com/geoip/updating-databases/ + responses: + "302": + description: >- + Redirects to a signed URL for the file. The response has no body. + The file name is + `_[_].`. + headers: + Location: + description: >- + The signed URL for the file, on the host + `mm-prod-geoip-databases.a2649acb697e2c09b632799562c076f2.r2.cloudflarestorage.com`. + Firewalls and proxies must allow HTTPS connections to this host. + schema: + type: string + "400": + $ref: "#/components/responses/DownloadBadRequest" + "401": + $ref: "#/components/responses/DownloadUnauthorized" + "403": + $ref: "#/components/responses/DownloadForbidden" + "404": + $ref: "#/components/responses/DownloadNotFound" + "429": + $ref: "#/components/responses/DownloadTooManyRequests" + "451": + $ref: "#/components/responses/DownloadLegalReasons" + "500": + $ref: "#/components/responses/DownloadInternalServerError" + "503": + $ref: "#/components/responses/DownloadServiceUnavailable" + head: + operationId: checkDatabaseBuildDate + summary: Check a database file's build date + description: >- + Returns the headers for the database file without its body. Use this to + check the `Last-Modified` build date before downloading. A HEAD request + does not count against the account's download limit. + tags: + - Database downloads + externalDocs: + description: Updating GeoIP and GeoLite databases documentation + url: https://dev.maxmind.com/geoip/updating-databases/ + responses: + "200": + description: The headers for the file. The response has no body. + headers: + Last-Modified: + description: The build date of the file. + schema: + type: string + Content-Disposition: + description: >- + `attachment`, with a `filename` of + `_[_].`. + schema: + type: string + Content-Type: + description: The media type for the `suffix` requested. + schema: + type: string + "400": + $ref: "#/components/responses/DownloadBadRequest" + "401": + $ref: "#/components/responses/DownloadUnauthorized" + "403": + $ref: "#/components/responses/DownloadForbidden" + "404": + $ref: "#/components/responses/DownloadNotFound" + "429": + $ref: "#/components/responses/DownloadTooManyRequests" + "451": + $ref: "#/components/responses/DownloadLegalReasons" + "500": + $ref: "#/components/responses/DownloadInternalServerError" + "503": + $ref: "#/components/responses/DownloadServiceUnavailable" + /geofeed/reports/v1.0/{geofeed_id}/{report_id}: + parameters: + - $ref: "#/components/parameters/GeofeedID" + - $ref: "#/components/parameters/ReportID" + get: + operationId: downloadGeofeedReport + summary: Download a geofeed report + description: >- + Redirects to a signed URL for a GeoIP Exchange geofeed report. + tags: + - Geofeed reports + externalDocs: + description: GeoIP Exchange documentation + url: https://dev.maxmind.com/geoip/geoip-exchange/ + responses: + "307": + description: >- + Redirects to a signed URL for the report. The file is + `.csv`. + headers: + Location: + description: >- + The signed URL for the report, on the host + `storage.googleapis.com`. + schema: + type: string + "400": + $ref: "#/components/responses/GeofeedBadRequest" + "401": + $ref: "#/components/responses/GeofeedUnauthorized" + "403": + $ref: "#/components/responses/GeofeedForbidden" + "404": + $ref: "#/components/responses/GeofeedNotFound" + "500": + $ref: "#/components/responses/GeofeedInternalServerError" + "503": + $ref: "#/components/responses/GeofeedServiceUnavailable" + head: + operationId: checkGeofeedReportBuildDate + summary: Check a geofeed report's build date + description: >- + Redirects to a signed URL for a GeoIP Exchange geofeed report, the same + as `GET`, but without a response body. Follow the redirect with HEAD. + The storage host's response has the `Last-Modified` build date, not this + 307 response. + tags: + - Geofeed reports + externalDocs: + description: GeoIP Exchange documentation + url: https://dev.maxmind.com/geoip/geoip-exchange/ + responses: + "307": + description: >- + Redirects to a signed URL for the report. The response has no body. + The file is `.csv`. + headers: + Location: + description: >- + The signed URL for the report, on the host + `storage.googleapis.com`. + schema: + type: string + "400": + $ref: "#/components/responses/GeofeedBadRequest" + "401": + $ref: "#/components/responses/GeofeedUnauthorized" + "403": + $ref: "#/components/responses/GeofeedForbidden" + "404": + $ref: "#/components/responses/GeofeedNotFound" + "500": + $ref: "#/components/responses/GeofeedInternalServerError" + "503": + $ref: "#/components/responses/GeofeedServiceUnavailable" +components: + securitySchemes: + basicAuth: + type: http + scheme: basic + description: >- + The username is your MaxMind account ID. The password is your MaxMind + license key. The service accepts HTTPS requests only. + parameters: + EditionID: + name: edition_id + in: path + required: true + description: >- + The edition ID of the database. Edition IDs are case sensitive. An ID + with the wrong case returns 404. + schema: + type: string + pattern: "^[A-Za-z0-9_-]+$" + examples: + city: + value: GeoIP2-City + cityCSV: + value: GeoIP2-City-CSV + Suffix: + name: suffix + in: query + required: true + description: >- + The file format to download. Binary editions use `tar.gz` and CSV + editions use `zip`. `csv` with `artifact_type` downloads a report for + either the binary or the CSV edition, for example the [location name + diff + report](https://dev.maxmind.com/geoip/track-location-name-updates/). + `tar.gz.md5`, `tar.gz.sha256`, `zip.md5`, and `zip.sha256` download a + checksum file for the matching archive instead of the archive itself. + schema: + type: string + enum: + - tar.gz + - zip + - csv + - tar.gz.md5 + - tar.gz.sha256 + - zip.md5 + - zip.sha256 + examples: + tarGz: + value: tar.gz + zip: + value: zip + csv: + value: csv + Date: + name: date + in: query + required: false + description: >- + Restricts the download to the release built on this date, in `YYYYMMDD` + format. If not present, MaxMind returns the latest release. + schema: + type: string + pattern: "^[0-9]{8}$" + examples: + date: + value: "20200121" + ArtifactType: + name: artifact_type + in: query + required: false + description: >- + The kind of artifact to download instead of the database file itself. + Known value: `Locations-Diff-Report`, paired with `suffix=csv`, for the + [location name diff + report](https://dev.maxmind.com/geoip/track-location-name-updates/). + MaxMind may add other values. + schema: + type: string + examples: + locationsDiffReport: + value: Locations-Diff-Report + GeofeedID: + name: geofeed_id + in: path + required: true + description: >- + The numeric ID for the geofeed, from the GeoIP Exchange section of your + account portal. + schema: + type: integer + minimum: 1 + examples: + geofeedID: + value: 12345 + ReportID: + name: report_id + in: path + required: true + description: The kind of geofeed report to download. + schema: + type: string + enum: + - free + - geolocation + - intelligence + examples: + geolocation: + value: geolocation + responses: + DownloadBadRequest: + description: >- + The request is not valid. The response does not have a JSON body, for + example `Invalid edition ID`, `Invalid suffix`, `Invalid date`, + `"" is an invalid date`, or `"" is an invalid artifact + type`. + DownloadUnauthorized: + description: >- + The credentials are missing or not valid. The response does not have a + JSON body, for example `An account ID and license key are required to + use this service.` or `Your account ID or license key could not be + authenticated.` + headers: + WWW-Authenticate: + description: + The authentication scheme, `Basic realm="geoip-download"`. + schema: + type: string + DownloadForbidden: + description: >- + The account cannot use this download service, or has no active + subscription for this database edition (free editions need no + subscription). The response does not have a JSON body, for example `You + do not have permission to use this service interface.` or `Invalid + product ID or subscription expired for `. + DownloadNotFound: + description: >- + No file matches the edition ID, date, and suffix, or the path does not + match a download URL. The response does not have a JSON body, for + example `Database edition "" not found`. + DownloadTooManyRequests: + description: >- + The account reached its download limit for a 24-hour period. The + response does not have a JSON body. + DownloadLegalReasons: + description: >- + MaxMind cannot provide this download for legal reasons. The response + does not have a JSON body, for example `Downloads are forbidden from + countries and territories on the US embargo list` or `Downloads of this + database from are forbidden due to US bulk sensitive data + transfer rules`. + DownloadInternalServerError: + description: >- + The service had an unexpected error. The response does not have a JSON + body. + DownloadServiceUnavailable: + description: >- + The service has a temporary problem. Send the request again later. The + response does not have a JSON body, for example `Unable to reach the + GeoIP download service. Please try again later.` + GeofeedBadRequest: + description: >- + The geofeed ID in the path is not a valid integer + (`GEOFEED_ID_INVALID`). + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: GEOFEED_ID_INVALID + error: "'abc' is not a valid geofeed_id." + GeofeedForbidden: + description: >- + The account does not have permission to download this kind of report + (`PERMISSION_REQUIRED`). A request that uses HTTP instead of HTTPS also + gets this status, but without a JSON body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: PERMISSION_REQUIRED + error: You do not have permission to use the service. + GeofeedUnauthorized: + description: >- + The credentials are missing or not valid. The `code` is one of: + + - `AUTHORIZATION_INVALID`: the account ID or license key is not valid. + + - `ACCOUNT_ID_REQUIRED`: the Basic credentials have no account ID. + + - `LICENSE_KEY_REQUIRED`: the Basic credentials have no license key. + headers: + WWW-Authenticate: + description: + The authentication scheme, `Basic realm="geofeed-report"`. + schema: + type: string + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: ACCOUNT_ID_REQUIRED + error: + An account ID and license key are required to use this service. + GeofeedNotFound: + description: >- + No report matches the geofeed ID and report kind, or the geofeed belongs + to a different account (`REPORT_NOT_FOUND`). Some 404 responses do not + have a JSON body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: REPORT_NOT_FOUND + error: Report not found with the given date. + GeofeedInternalServerError: + description: >- + The service had an unexpected error (`SERVER_ERROR`). + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: SERVER_ERROR + error: There was an error when processing this request. + GeofeedServiceUnavailable: + description: >- + The service has a temporary problem. Send the request again later. The + response does not have a JSON body. diff --git a/specs/license-key-validation.yaml b/specs/license-key-validation.yaml new file mode 100644 index 0000000..a896dbf --- /dev/null +++ b/specs/license-key-validation.yaml @@ -0,0 +1,139 @@ +openapi: 3.1.2 +info: + title: License Key Validation API + version: 0.1.0 + summary: + Check whether a license key has a valid format and is known to MaxMind. + description: >- + The License Key Validation API checks whether a license key has a valid + format and whether MaxMind knows the key. It does not check what products or + services the license key can access, or return the account that owns the + key. Use this API to scan your own code and configuration for secrets, so + that license keys do not end up in places you did not intend. + + + Clients must handle any 4xx or 5xx status and check `Content-Type` before + they decode an error body. + contact: + name: MaxMind support + url: https://support.maxmind.com/ + license: + name: Apache 2.0 or MIT + identifier: Apache-2.0 OR MIT + termsOfService: https://www.maxmind.com/en/terms-of-use +externalDocs: + description: License Key Validation API documentation + url: https://dev.maxmind.com/license-key-validation-api/ +servers: + - url: https://secret-scanning.maxmind.com + description: License key validation +tags: + - name: License key validation + description: Check a license key's format and validity. +paths: + /secrets/validate-license-key: + post: + operationId: validateLicenseKey + summary: Validate a license key + description: >- + Checks whether a license key has a valid format and is known to MaxMind. + The request carries the license key to validate, so it needs no other + authorization. + tags: + - License key validation + security: [] + externalDocs: + description: License Key Validation API documentation + url: https://dev.maxmind.com/license-key-validation-api/ + requestBody: + description: + The request body must use `application/x-www-form-urlencoded`. + required: true + content: + application/x-www-form-urlencoded: + schema: + type: object + required: + - license_key + properties: + license_key: + type: string + description: The license key to validate. + examples: + validate: + summary: A license key to validate + value: + license_key: your_license_key_here + responses: + "204": + description: The license key has a valid format and MaxMind knows it. + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "403": + $ref: "#/components/responses/Forbidden" + "413": + $ref: "#/components/responses/PayloadTooLarge" + "500": + $ref: "#/components/responses/InternalServerError" + "503": + $ref: "#/components/responses/ServiceUnavailable" +components: + responses: + BadRequest: + description: >- + The request is not valid (`LICENSE_KEY_INVALID`). This happens when the + `license_key` field is missing, empty, or not in the format of a MaxMind + license key. + content: + application/json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: LICENSE_KEY_INVALID + error: + "'foo-bad-license-key' is not a valid license_key when calling + /secrets/validate-license-key." + Unauthorized: + description: >- + The license key has a valid format, but MaxMind does not know it + (`AUTHORIZATION_INVALID`). + content: + application/json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: AUTHORIZATION_INVALID + error: Your account ID or license key could not be authenticated. + Forbidden: + description: >- + The account that owns the license key does not have permission to use + this service (`PERMISSION_REQUIRED`). This response means that MaxMind + recognizes the key. An unknown key gets a 401 response instead. A + request that uses HTTP instead of HTTPS also gets this status, but + without a JSON body. + content: + application/json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: PERMISSION_REQUIRED + error: You do not have permission to use this service interface. + PayloadTooLarge: + description: >- + The request body is too large. The response does not have a JSON body. + InternalServerError: + description: >- + The service had an unexpected error (`SERVER_ERROR`). + content: + application/json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: SERVER_ERROR + error: There was an error when processing this request. + ServiceUnavailable: + description: >- + The service has a temporary problem. Send the request again later. The + response does not have a JSON body. diff --git a/specs/privacy-exclusions.yaml b/specs/privacy-exclusions.yaml new file mode 100644 index 0000000..2ab5812 --- /dev/null +++ b/specs/privacy-exclusions.yaml @@ -0,0 +1,204 @@ +openapi: 3.1.2 +info: + title: Privacy Exclusions API + version: 0.1.0 + summary: Retrieve Do Not Sell My Personal Information exclusion requests. + description: >- + The Privacy Exclusions API returns the networks that MaxMind excludes from + its services under Do Not Sell My Personal Information requests, such as + those made under the California Consumer Privacy Act (CCPA). + + + A successful response has the `Content-Type` header + `application/vnd.maxmind.com-privacy-exclusions+json; charset=UTF-8; + version=1.0`. An error response has `application/vnd.maxmind.com-error+json; + charset=UTF-8; version=2.0`. + + + Clients must handle any 4xx or 5xx status and check `Content-Type` before + they decode an error body. + contact: + name: MaxMind support + url: https://support.maxmind.com/ + license: + name: Apache 2.0 or MIT + identifier: Apache-2.0 OR MIT + termsOfService: https://www.maxmind.com/en/terms-of-use +externalDocs: + description: Privacy Exclusions API documentation + url: https://dev.maxmind.com/geoip/privacy-exclusions-api/ +servers: + - url: https://api.maxmind.com + description: MaxMind web services +security: + - basicAuth: [] +tags: + - name: Privacy exclusions + description: Privacy exclusion requests. +paths: + /privacy/exclusions: + get: + operationId: getPrivacyExclusions + summary: List privacy exclusions + description: >- + Returns the current Do Not Sell My Personal Information exclusions. Each + exclusion is a network that MaxMind excludes from its services. The + response always includes a `Content-Length` header. + tags: + - Privacy exclusions + externalDocs: + description: Privacy Exclusions API documentation + url: https://dev.maxmind.com/geoip/privacy-exclusions-api/ + parameters: + - $ref: "#/components/parameters/UpdatesAfter" + responses: + "200": + description: The current privacy exclusions. + content: + application/vnd.maxmind.com-privacy-exclusions+json: + schema: + $ref: "#/components/schemas/ExclusionsResponse" + examples: + exclusions: + $ref: "../examples/privacy-exclusions/exclusions.yaml" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "403": + $ref: "#/components/responses/Forbidden" + "500": + $ref: "#/components/responses/InternalServerError" + "503": + $ref: "#/components/responses/ServiceUnavailable" +components: + securitySchemes: + basicAuth: + type: http + scheme: basic + description: >- + The username is your MaxMind account ID. The password is your MaxMind + license key. The service accepts HTTPS requests only, with TLS 1.2 or + higher. The authorization realm is `privacy-exclusion`. + parameters: + UpdatesAfter: + name: updates_after + in: query + required: false + description: >- + If present, the response includes only exclusions updated after this + time. The value is an RFC 3339 timestamp. URL-encode the value, for + example send a `+` in the UTC offset as `%2B`. + schema: + type: string + format: date-time + examples: + updatesAfter: + value: "2020-04-12T23:20:50.52Z" + schemas: + Exclusion: + type: object + description: >- + A single privacy exclusion request. MaxMind can add keys in the future. + required: + - exclusion_type + - data_type + - value + - last_updated + properties: + exclusion_type: + type: string + description: >- + The governing law or rule for the exclusion. Currently the only + value is `ccpa_do_not_sell`, for a request made under the California + Consumer Privacy Act. + data_type: + type: string + description: >- + The type of the `value` field. Known value: `network`, an IP network + in CIDR notation. All IP addresses in the network are excluded. + Check this field before you use the associated `value`. MaxMind may + add other values. + value: + type: string + description: + The excluded value, in the format the `data_type` field gives. + last_updated: + type: string + format: date-time + description: + The RFC 3339 timestamp of the last update to the exclusion. + ExclusionsResponse: + type: object + description: >- + The Privacy Exclusions response. MaxMind can add keys in the future. + required: + - exclusions + properties: + exclusions: + type: array + description: >- + The current privacy exclusions. Empty if there are none. + items: + $ref: "#/components/schemas/Exclusion" + responses: + BadRequest: + description: >- + The request is not valid (`TIMESTAMP_INVALID`). The `updates_after` + value is not a valid RFC 3339 timestamp. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: TIMESTAMP_INVALID + error: The updates_after field must be in RFC 3339 format. + Unauthorized: + description: >- + The credentials are missing or not valid. The `code` is one of: + + - `AUTHORIZATION_INVALID`: the account ID or license key is not valid. + + - `ACCOUNT_ID_REQUIRED`: the Basic credentials have no account ID. + + - `LICENSE_KEY_REQUIRED`: the Basic credentials have no license key. + headers: + WWW-Authenticate: + description: >- + The authentication scheme, `Basic realm="privacy-exclusion"`. + schema: + type: string + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: ACCOUNT_ID_REQUIRED + error: + An account ID and license key are required to use this service. + Forbidden: + description: >- + The account does not have permission to use this service + (`PERMISSION_REQUIRED`). A request that uses HTTP instead of HTTPS also + gets this status, but without a JSON body. + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: PERMISSION_REQUIRED + error: You do not have permission to use the service. + InternalServerError: + description: >- + The service had an unexpected error (`SERVER_ERROR`). + content: + application/vnd.maxmind.com-error+json: + schema: + $ref: "../components/errors.yaml#/schemas/Error" + example: + code: SERVER_ERROR + error: There was an error when processing this request. + ServiceUnavailable: + description: >- + The service has a temporary problem. Check https://status.maxmind.com, + or send the request again later. The response does not have a JSON body. From 2f994860a90522636a56a22306d494342096c913 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:36:49 +0000 Subject: [PATCH 04/31] Detect removed and renamed bundles in CI --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aa7bc2a..9703ce9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,9 +29,10 @@ jobs: - name: Check that the bundles are current run: | + rm -rf bundled pnpm run bundle git add --intent-to-add bundled/ - git diff --exit-code bundled/ + git diff --exit-code HEAD -- bundled/ - name: Vet the Go package run: go vet ./... From 5129765889f8e8ba65b01ee86bb762edaa35f6c4 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:36:53 +0000 Subject: [PATCH 05/31] Remove ignored HEAD Content-Type header --- bundled/downloads.yaml | 4 ---- specs/downloads.yaml | 4 ---- 2 files changed, 8 deletions(-) diff --git a/bundled/downloads.yaml b/bundled/downloads.yaml index d8088c5..0517a33 100644 --- a/bundled/downloads.yaml +++ b/bundled/downloads.yaml @@ -90,10 +90,6 @@ paths: description: '`attachment`, with a `filename` of `_[_].`.' schema: type: string - Content-Type: - description: The media type for the `suffix` requested. - schema: - type: string '400': $ref: '#/components/responses/DownloadBadRequest' '401': diff --git a/specs/downloads.yaml b/specs/downloads.yaml index 3328677..253b8ea 100644 --- a/specs/downloads.yaml +++ b/specs/downloads.yaml @@ -118,10 +118,6 @@ paths: `_[_].`. schema: type: string - Content-Type: - description: The media type for the `suffix` requested. - schema: - type: string "400": $ref: "#/components/responses/DownloadBadRequest" "401": From 5ae3d48575e6d6c42e68cd5494b39eac55f88fac Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:36:56 +0000 Subject: [PATCH 06/31] Correct the default string limit wording --- bundled/minfraud.yaml | 2 +- components/minfraud-request.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index ca2feec..2d7fdb7 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -988,7 +988,7 @@ components: MaxMind can add fields to the request body without a version change. A field that MaxMind does not recognize produces an `INPUT_UNKNOWN` warning. - A string field allows up to 255 valid Unicode characters unless its schema states a shorter limit. Null and newline characters are not allowed. MaxMind accepts a number sent as a string and a string sent as a number, and converts it to the type the field requires. + A string field allows up to 255 valid Unicode characters unless its schema states a different limit. Null and newline characters are not allowed. MaxMind accepts a number sent as a string and a string sent as a number, and converts it to the type the field requires. A value that does not meet a field's constraints, such as its pattern, enum, or length, produces an `INPUT_INVALID` warning in the response. The request still succeeds. minProperties: 1 diff --git a/components/minfraud-request.yaml b/components/minfraud-request.yaml index dda8136..eecdc5d 100644 --- a/components/minfraud-request.yaml +++ b/components/minfraud-request.yaml @@ -12,7 +12,7 @@ schemas: A string field allows up to 255 valid Unicode characters unless its schema - states a shorter limit. Null and newline characters are not allowed. + states a different limit. Null and newline characters are not allowed. MaxMind accepts a number sent as a string and a string sent as a number, and converts it to the type the field requires. From 8f96f9f5e410d06743d79f30897b72da36920660 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:37:40 +0000 Subject: [PATCH 07/31] Use a valid email domain first-seen date --- bundled/minfraud.yaml | 4 ++-- examples/minfraud/factors.yaml | 2 +- examples/minfraud/insights.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index 2d7fdb7..0b5e4d9 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -2173,7 +2173,7 @@ components: email: domain: classification: business - first_seen: '2015-01-20' + first_seen: '2019-01-20' risk: 1.23 visit: has_redirect: true @@ -2375,7 +2375,7 @@ components: email: domain: classification: business - first_seen: '2015-01-20' + first_seen: '2019-01-20' risk: 1.23 visit: has_redirect: true diff --git a/examples/minfraud/factors.yaml b/examples/minfraud/factors.yaml index 7500949..3f33e0c 100644 --- a/examples/minfraud/factors.yaml +++ b/examples/minfraud/factors.yaml @@ -178,7 +178,7 @@ value: email: domain: classification: business - first_seen: "2015-01-20" + first_seen: "2019-01-20" risk: 1.23 visit: has_redirect: true diff --git a/examples/minfraud/insights.yaml b/examples/minfraud/insights.yaml index 2bd20b5..fa34a97 100644 --- a/examples/minfraud/insights.yaml +++ b/examples/minfraud/insights.yaml @@ -178,7 +178,7 @@ value: email: domain: classification: business - first_seen: "2015-01-20" + first_seen: "2019-01-20" risk: 1.23 visit: has_redirect: true From 8e9975972ba5bca81bb786cea44d102d3a63c5a6 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:37:47 +0000 Subject: [PATCH 08/31] Align disposition reasons with rule labels --- bundled/minfraud.yaml | 6 +++--- examples/minfraud/factors.yaml | 2 +- examples/minfraud/insights.yaml | 2 +- examples/minfraud/score.yaml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index 0b5e4d9..5811b2b 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -1974,7 +1974,7 @@ components: value: disposition: action: accept - reason: default + reason: custom_rule rule_label: my_custom_rule funds_remaining: 25 id: 5bc5d6c2-b2c8-40af-87f4-6d61af86b6ae @@ -2001,7 +2001,7 @@ components: value: disposition: action: accept - reason: default + reason: custom_rule rule_label: my_custom_rule funds_remaining: 25 id: 5bc5d6c2-b2c8-40af-87f4-6d61af86b6ae @@ -2203,7 +2203,7 @@ components: value: disposition: action: accept - reason: default + reason: custom_rule rule_label: my_custom_rule funds_remaining: 25 id: 5bc5d6c2-b2c8-40af-87f4-6d61af86b6ae diff --git a/examples/minfraud/factors.yaml b/examples/minfraud/factors.yaml index 3f33e0c..efbeb69 100644 --- a/examples/minfraud/factors.yaml +++ b/examples/minfraud/factors.yaml @@ -2,7 +2,7 @@ summary: minFraud Factors response value: disposition: action: accept - reason: default + reason: custom_rule rule_label: my_custom_rule funds_remaining: 25 id: 5bc5d6c2-b2c8-40af-87f4-6d61af86b6ae diff --git a/examples/minfraud/insights.yaml b/examples/minfraud/insights.yaml index fa34a97..7116dc6 100644 --- a/examples/minfraud/insights.yaml +++ b/examples/minfraud/insights.yaml @@ -2,7 +2,7 @@ summary: minFraud Insights response value: disposition: action: accept - reason: default + reason: custom_rule rule_label: my_custom_rule funds_remaining: 25 id: 5bc5d6c2-b2c8-40af-87f4-6d61af86b6ae diff --git a/examples/minfraud/score.yaml b/examples/minfraud/score.yaml index f19623a..85d7c48 100644 --- a/examples/minfraud/score.yaml +++ b/examples/minfraud/score.yaml @@ -2,7 +2,7 @@ summary: minFraud Score response value: disposition: action: accept - reason: default + reason: custom_rule rule_label: my_custom_rule funds_remaining: 25 id: 5bc5d6c2-b2c8-40af-87f4-6d61af86b6ae From c4e038f67b13757d5234cf4edddec27d2db94c83 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:38:17 +0000 Subject: [PATCH 09/31] Clarify the illustrative response examples --- bundled/geoip.yaml | 9 +++++++++ bundled/minfraud.yaml | 9 +++++++++ examples/geoip/city.yaml | 5 +++++ examples/geoip/country.yaml | 5 +++++ examples/geoip/insights.yaml | 5 +++++ examples/minfraud/factors.yaml | 6 ++++++ examples/minfraud/insights.yaml | 6 ++++++ examples/minfraud/score.yaml | 3 +++ 8 files changed, 48 insertions(+) diff --git a/bundled/geoip.yaml b/bundled/geoip.yaml index bac4e11..403c072 100644 --- a/bundled/geoip.yaml +++ b/bundled/geoip.yaml @@ -687,6 +687,7 @@ components: examples: country: summary: GeoIP Country response + description: These illustrative values show available fields and do not describe a single real lookup. value: continent: code: NA @@ -716,6 +717,7 @@ components: queries_remaining: 54321 registered_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -728,6 +730,7 @@ components: zh-CN: 美国 represented_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -745,6 +748,7 @@ components: network: 1.2.3.0/24 city: summary: GeoIP City Plus response + description: These illustrative values show available fields and do not describe a single real lookup. value: continent: code: NA @@ -774,6 +778,7 @@ components: queries_remaining: 54321 registered_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -786,6 +791,7 @@ components: zh-CN: 美国 represented_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -841,6 +847,7 @@ components: zh-CN: 加州 insights: summary: GeoIP Insights response + description: These illustrative values show available fields and do not describe a single real lookup. value: continent: code: NA @@ -871,6 +878,7 @@ components: queries_remaining: 54321 registered_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -883,6 +891,7 @@ components: zh-CN: 美国 represented_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index 5811b2b..3736134 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -1971,6 +1971,7 @@ components: quantity: 1 score: summary: minFraud Score response + description: These illustrative values show available fields and do not describe a single real transaction. value: disposition: action: accept @@ -1998,6 +1999,7 @@ components: error: You do not have sufficient funds to use this service. insights: summary: minFraud Insights response + description: These illustrative values show available fields and do not describe a single real transaction. value: disposition: action: accept @@ -2048,6 +2050,7 @@ components: country: confidence: 75 geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -2072,6 +2075,7 @@ components: confidence: 10 registered_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -2084,6 +2088,7 @@ components: zh-CN: 美国 represented_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -2200,6 +2205,7 @@ components: number_type: mobile factors: summary: minFraud Factors response + description: These illustrative values show available fields and do not describe a single real transaction. value: disposition: action: accept @@ -2250,6 +2256,7 @@ components: country: confidence: 75 geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -2274,6 +2281,7 @@ components: confidence: 10 registered_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -2286,6 +2294,7 @@ components: zh-CN: 美国 represented_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA diff --git a/examples/geoip/city.yaml b/examples/geoip/city.yaml index 95ce032..1a0858a 100644 --- a/examples/geoip/city.yaml +++ b/examples/geoip/city.yaml @@ -1,4 +1,7 @@ summary: GeoIP City Plus response +description: >- + These illustrative values show available fields and do not describe a single + real lookup. value: continent: code: NA @@ -28,6 +31,7 @@ value: queries_remaining: 54321 registered_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -40,6 +44,7 @@ value: zh-CN: 美国 represented_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA diff --git a/examples/geoip/country.yaml b/examples/geoip/country.yaml index ea11367..212b04d 100644 --- a/examples/geoip/country.yaml +++ b/examples/geoip/country.yaml @@ -1,4 +1,7 @@ summary: GeoIP Country response +description: >- + These illustrative values show available fields and do not describe a single + real lookup. value: continent: code: NA @@ -28,6 +31,7 @@ value: queries_remaining: 54321 registered_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -40,6 +44,7 @@ value: zh-CN: 美国 represented_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA diff --git a/examples/geoip/insights.yaml b/examples/geoip/insights.yaml index 7700af7..0ae13b8 100644 --- a/examples/geoip/insights.yaml +++ b/examples/geoip/insights.yaml @@ -1,4 +1,7 @@ summary: GeoIP Insights response +description: >- + These illustrative values show available fields and do not describe a single + real lookup. value: continent: code: NA @@ -29,6 +32,7 @@ value: queries_remaining: 54321 registered_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -41,6 +45,7 @@ value: zh-CN: 美国 represented_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA diff --git a/examples/minfraud/factors.yaml b/examples/minfraud/factors.yaml index efbeb69..235cbcf 100644 --- a/examples/minfraud/factors.yaml +++ b/examples/minfraud/factors.yaml @@ -1,4 +1,7 @@ summary: minFraud Factors response +description: >- + These illustrative values show available fields and do not describe a single + real transaction. value: disposition: action: accept @@ -49,6 +52,7 @@ value: country: confidence: 75 geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -73,6 +77,7 @@ value: confidence: 10 registered_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -85,6 +90,7 @@ value: zh-CN: 美国 represented_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA diff --git a/examples/minfraud/insights.yaml b/examples/minfraud/insights.yaml index 7116dc6..460e00f 100644 --- a/examples/minfraud/insights.yaml +++ b/examples/minfraud/insights.yaml @@ -1,4 +1,7 @@ summary: minFraud Insights response +description: >- + These illustrative values show available fields and do not describe a single + real transaction. value: disposition: action: accept @@ -49,6 +52,7 @@ value: country: confidence: 75 geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -73,6 +77,7 @@ value: confidence: 10 registered_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA @@ -85,6 +90,7 @@ value: zh-CN: 美国 represented_country: geoname_id: 6252001 + is_in_european_union: true iso_code: US names: de: USA diff --git a/examples/minfraud/score.yaml b/examples/minfraud/score.yaml index 85d7c48..eea1bd1 100644 --- a/examples/minfraud/score.yaml +++ b/examples/minfraud/score.yaml @@ -1,4 +1,7 @@ summary: minFraud Score response +description: >- + These illustrative values show available fields and do not describe a single + real transaction. value: disposition: action: accept From 3f62af88a06e6ce372483d1c16f585d33864e1e3 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:38:24 +0000 Subject: [PATCH 10/31] Describe valid device IP address formats --- bundled/minfraud.yaml | 4 +++- components/minfraud-request.yaml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index 3736134..8dbb169 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -623,7 +623,9 @@ components: description: The HTTP `Accept-Language` header of the device. ip_address: type: string - maxLength: 255 + anyOf: + - format: ipv4 + - format: ipv6 description: The IPv4 or IPv6 address of the device, in presentation format (dotted-quad notation or IPv6 colon notation). A private or reserved address produces an `IP_ADDRESS_RESERVED` warning. session_age: type: number diff --git a/components/minfraud-request.yaml b/components/minfraud-request.yaml index eecdc5d..68b7d08 100644 --- a/components/minfraud-request.yaml +++ b/components/minfraud-request.yaml @@ -65,7 +65,9 @@ schemas: description: The HTTP `Accept-Language` header of the device. ip_address: type: string - maxLength: 255 + anyOf: + - format: ipv4 + - format: ipv6 description: >- The IPv4 or IPv6 address of the device, in presentation format (dotted-quad notation or IPv6 colon notation). A private or reserved From 6bf086c785a8e4d5aa56f0856a6d846d2840a0fe Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:38:27 +0000 Subject: [PATCH 11/31] Require all disposition update keys --- bundled/minfraud.yaml | 4 ++++ components/minfraud-response.yaml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index 8dbb169..5b6f106 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -1844,7 +1844,11 @@ components: DispositionUpdate: type: object required: + - action + - action_last_updated - minfraud_id + - note + - note_last_updated properties: action: type: diff --git a/components/minfraud-response.yaml b/components/minfraud-response.yaml index b11dbe2..ca4b83e 100644 --- a/components/minfraud-response.yaml +++ b/components/minfraud-response.yaml @@ -673,7 +673,11 @@ schemas: DispositionUpdate: type: object required: + - action + - action_last_updated - minfraud_id + - note + - note_last_updated properties: action: type: From dc1e94d5b2a972909d779bb100f7a910aaac7ee2 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:39:13 +0000 Subject: [PATCH 12/31] Allow future continent response codes --- bundled/geoip.yaml | 12 ++---------- bundled/minfraud.yaml | 10 +--------- components/geoip-records.yaml | 12 +++--------- specs/geoip.yaml | 7 +++---- 4 files changed, 9 insertions(+), 32 deletions(-) diff --git a/bundled/geoip.yaml b/bundled/geoip.yaml index 403c072..9ba6732 100644 --- a/bundled/geoip.yaml +++ b/bundled/geoip.yaml @@ -12,7 +12,7 @@ info: A successful response has a `Content-Type` of `application/vnd.maxmind.com-+json; charset=UTF-8; version=2.1`, for example `application/vnd.maxmind.com-city+json; charset=UTF-8; version=2.1`. An error response has a `Content-Type` of `application/vnd.maxmind.com-error+json; charset=UTF-8; version=2.1`. - MaxMind can add new values to an enumerated field, other than the fixed continent codes, and new locale codes. MaxMind can also add or remove error codes. Clients must handle any 4xx or 5xx status and check `Content-Type` before they decode an error body. + MaxMind can add new values to an enumerated field and new locale codes. MaxMind can also add or remove error codes. Clients must handle any 4xx or 5xx status and check `Content-Type` before they decode an error body. contact: name: MaxMind support url: https://support.maxmind.com/ @@ -262,15 +262,7 @@ components: properties: code: type: string - description: The two-character code for the continent. - enum: - - AF - - AN - - AS - - EU - - NA - - OC - - SA + description: 'The two-character code for the continent. Known values: `AF`, `AN`, `AS`, `EU`, `NA`, `OC`, and `SA`. MaxMind may add values.' geoname_id: type: integer minimum: 0 diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index 5b6f106..c2a7e98 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -1395,15 +1395,7 @@ components: properties: code: type: string - description: The two-character code for the continent. - enum: - - AF - - AN - - AS - - EU - - NA - - OC - - SA + description: 'The two-character code for the continent. Known values: `AF`, `AN`, `AS`, `EU`, `NA`, `OC`, and `SA`. MaxMind may add values.' geoname_id: type: integer minimum: 0 diff --git a/components/geoip-records.yaml b/components/geoip-records.yaml index 7925105..0061d84 100644 --- a/components/geoip-records.yaml +++ b/components/geoip-records.yaml @@ -15,15 +15,9 @@ schemas: properties: code: type: string - description: The two-character code for the continent. - enum: - - AF - - AN - - AS - - EU - - NA - - OC - - SA + description: >- + The two-character code for the continent. Known values: `AF`, `AN`, + `AS`, `EU`, `NA`, `OC`, and `SA`. MaxMind may add values. geoname_id: type: integer minimum: 0 diff --git a/specs/geoip.yaml b/specs/geoip.yaml index 53702e4..b3b265b 100644 --- a/specs/geoip.yaml +++ b/specs/geoip.yaml @@ -25,10 +25,9 @@ info: `application/vnd.maxmind.com-error+json; charset=UTF-8; version=2.1`. - MaxMind can add new values to an enumerated field, other than the fixed - continent codes, and new locale codes. MaxMind can also add or remove error - codes. Clients must handle any 4xx or 5xx status and check `Content-Type` - before they decode an error body. + MaxMind can add new values to an enumerated field and new locale codes. + MaxMind can also add or remove error codes. Clients must handle any 4xx or + 5xx status and check `Content-Type` before they decode an error body. contact: name: MaxMind support url: https://support.maxmind.com/ From b0feeaf24d874296bc1135c10ce2dd5ba3bc98ec Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:39:21 +0000 Subject: [PATCH 13/31] Align AVS characters with public clients --- bundled/minfraud.yaml | 2 +- components/minfraud-request.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index c2a7e98..8ba1338 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -563,7 +563,7 @@ components: properties: avs_result: type: string - pattern: ^[A-Za-z1-4]$ + pattern: ^[A-Za-z0-9]$ description: The address verification system (AVS) check result, as your payment processor returns it. MaxMind supports the standard AVS codes. bank_name: type: string diff --git a/components/minfraud-request.yaml b/components/minfraud-request.yaml index 68b7d08..8b102ec 100644 --- a/components/minfraud-request.yaml +++ b/components/minfraud-request.yaml @@ -500,7 +500,7 @@ schemas: properties: avs_result: type: string - pattern: "^[A-Za-z1-4]$" + pattern: "^[A-Za-z0-9]$" description: >- The address verification system (AVS) check result, as your payment processor returns it. MaxMind supports the standard AVS codes. From eb51bfb4dea1769f4babd6b016044cbaf4c3f227 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:39:24 +0000 Subject: [PATCH 14/31] Clarify GeoLite account object availability --- bundled/geoip.yaml | 4 ++-- components/geoip-records.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bundled/geoip.yaml b/bundled/geoip.yaml index 9ba6732..7256d0d 100644 --- a/bundled/geoip.yaml +++ b/bundled/geoip.yaml @@ -287,12 +287,12 @@ components: $ref: '#/components/schemas/Names' MaxMind: type: object - description: Information about your MaxMind account. + description: Information about your MaxMind account. The GeoLite Country and GeoLite City web services do not return this object. properties: queries_remaining: type: integer minimum: 0 - description: The approximate number of queries left for the endpoint you called. The GeoLite City web service does not include this field. + description: The approximate number of queries left for the endpoint you called. RepresentedCountry: description: The country represented by users of an IP address, for example the country represented by an overseas military base. allOf: diff --git a/components/geoip-records.yaml b/components/geoip-records.yaml index 0061d84..a73cfa6 100644 --- a/components/geoip-records.yaml +++ b/components/geoip-records.yaml @@ -436,14 +436,14 @@ schemas: MaxMind: type: object description: >- - Information about your MaxMind account. + Information about your MaxMind account. The GeoLite Country and GeoLite + City web services do not return this object. properties: queries_remaining: type: integer minimum: 0 description: >- The approximate number of queries left for the endpoint you called. - The GeoLite City web service does not include this field. CountryResponse: type: object required: From 39124cacdcb78f3d9fa03100bc101a72bb423cb9 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:39:27 +0000 Subject: [PATCH 15/31] Specify disposition update sort direction --- bundled/minfraud.yaml | 2 +- components/minfraud-response.yaml | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index 8ba1338..70a60ad 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -1881,7 +1881,7 @@ components: description: The sort timestamp of the last transaction in `updates`, in RFC 3339 format with microsecond precision. This can differ from that transaction's `action_last_updated` and `note_last_updated`. Pass this value as `updates_after` in your next request. An empty `updates` array means there are no updates after `updates_after` yet. This value is then not a transaction's timestamp, so keep your current `updates_after` for the next request. updates: type: array - description: The transactions with a disposition or note update after `updates_after`, including a transaction whose manual review period expired. MaxMind sorts by the earliest update timestamp, either the disposition or the note, after `updates_after`. A response usually holds at most 1000 updated transactions. Do not rely on this limit. A transaction can appear in more than one response, for example when its note changes after its disposition, so process updates idempotently. + description: The transactions with a disposition or note update after `updates_after`, including a transaction whose manual review period expired. MaxMind sorts in ascending order by the earliest update timestamp, either the disposition or the note, after `updates_after`. A response usually holds at most 1000 updated transactions. Do not rely on this limit. A transaction can appear in more than one response, for example when its note changes after its disposition, so process updates idempotently. items: $ref: '#/components/schemas/DispositionUpdate' examples: diff --git a/components/minfraud-response.yaml b/components/minfraud-response.yaml index ca4b83e..2bf1ec1 100644 --- a/components/minfraud-response.yaml +++ b/components/minfraud-response.yaml @@ -663,11 +663,12 @@ schemas: description: >- The transactions with a disposition or note update after `updates_after`, including a transaction whose manual review period - expired. MaxMind sorts by the earliest update timestamp, either the - disposition or the note, after `updates_after`. A response usually - holds at most 1000 updated transactions. Do not rely on this limit. A - transaction can appear in more than one response, for example when its - note changes after its disposition, so process updates idempotently. + expired. MaxMind sorts in ascending order by the earliest update + timestamp, either the disposition or the note, after `updates_after`. + A response usually holds at most 1000 updated transactions. Do not + rely on this limit. A transaction can appear in more than one + response, for example when its note changes after its disposition, so + process updates idempotently. items: $ref: "#/schemas/DispositionUpdate" DispositionUpdate: From adf0dca5107e5f295165849acefed7c3dfc5c592 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:39:30 +0000 Subject: [PATCH 16/31] Clarify the event time recommendation --- bundled/minfraud.yaml | 2 +- components/minfraud-request.yaml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index 70a60ad..3af8082 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -671,7 +671,7 @@ components: type: string format: date-time description: |- - The time the event occurred, in RFC 3339 format. If you omit this field, MaxMind uses the time it receives the request. Do not send this field for a live transaction. Use it only for a stored transaction that you score later. + The time the event occurred, in RFC 3339 format. If you omit this field, MaxMind uses the time it receives the request. MaxMind does not recommend this field for live transactions. It can be useful for stored transactions that you score later. The time must be within the past year. For an older time, MaxMind uses the current time to score the transaction and returns a warning. transaction_id: diff --git a/components/minfraud-request.yaml b/components/minfraud-request.yaml index 8b102ec..fb4ad43 100644 --- a/components/minfraud-request.yaml +++ b/components/minfraud-request.yaml @@ -115,9 +115,9 @@ schemas: format: date-time description: >- The time the event occurred, in RFC 3339 format. If you omit this - field, MaxMind uses the time it receives the request. Do not send this - field for a live transaction. Use it only for a stored transaction - that you score later. + field, MaxMind uses the time it receives the request. MaxMind does not + recommend this field for live transactions. It can be useful for + stored transactions that you score later. The time must be within the past year. For an older time, MaxMind uses From 58688576cf00933e49f84e9022d0806087347ab6 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:39:33 +0000 Subject: [PATCH 17/31] Allow bodyless minFraud server errors --- bundled/minfraud.yaml | 2 +- specs/minfraud.yaml | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index 3af8082..33d8915 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -489,7 +489,7 @@ components: TooManyRequests: description: MaxMind rate-limited the request, usually because of too many earlier error responses. The response may have no body. InternalServerError: - description: The service had an unexpected error (`SERVER_ERROR`). + description: The service had an unexpected error (`SERVER_ERROR`). The response may have no JSON body. content: application/vnd.maxmind.com-error+json: schema: diff --git a/specs/minfraud.yaml b/specs/minfraud.yaml index 7b9a053..c68063b 100644 --- a/specs/minfraud.yaml +++ b/specs/minfraud.yaml @@ -585,7 +585,9 @@ components: MaxMind rate-limited the request, usually because of too many earlier error responses. The response may have no body. InternalServerError: - description: The service had an unexpected error (`SERVER_ERROR`). + description: >- + The service had an unexpected error (`SERVER_ERROR`). The response may + have no JSON body. content: application/vnd.maxmind.com-error+json: schema: From f6a8da58186e2d26b0fa50d8efe58f84b522dd11 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:40:52 +0000 Subject: [PATCH 18/31] Remove the undocumented GeoIP service error --- bundled/geoip.yaml | 1 - specs/geoip.yaml | 3 --- 2 files changed, 4 deletions(-) diff --git a/bundled/geoip.yaml b/bundled/geoip.yaml index 7256d0d..6967885 100644 --- a/bundled/geoip.yaml +++ b/bundled/geoip.yaml @@ -184,7 +184,6 @@ components: - `IP_ADDRESS_REQUIRED`: the request has an empty IP address. - `IP_ADDRESS_INVALID`: the IP address is not a valid IPv4 or IPv6 address. - `IP_ADDRESS_RESERVED`: the IP address is in a reserved or private range. - - `SERVICE_INVALID`: the service is not available on this host. On `geolite.info`, only Country and City are available. content: application/vnd.maxmind.com-error+json: schema: diff --git a/specs/geoip.yaml b/specs/geoip.yaml index b3b265b..1434229 100644 --- a/specs/geoip.yaml +++ b/specs/geoip.yaml @@ -225,9 +225,6 @@ components: - `IP_ADDRESS_RESERVED`: the IP address is in a reserved or private range. - - - `SERVICE_INVALID`: the service is not available on this host. On - `geolite.info`, only Country and City are available. content: application/vnd.maxmind.com-error+json: schema: From f1ade1e863171f54bbc79998382eb62453f17084 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:41:03 +0000 Subject: [PATCH 19/31] Describe privacy exclusion rate limiting --- bundled/privacy-exclusions.yaml | 4 ++++ specs/privacy-exclusions.yaml | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/bundled/privacy-exclusions.yaml b/bundled/privacy-exclusions.yaml index 93d57bb..2cd0279 100644 --- a/bundled/privacy-exclusions.yaml +++ b/bundled/privacy-exclusions.yaml @@ -56,6 +56,8 @@ paths: $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' + '429': + $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' '503': @@ -166,6 +168,8 @@ components: example: code: PERMISSION_REQUIRED error: You do not have permission to use the service. + TooManyRequests: + description: MaxMind rate-limited the request, usually because of excessive earlier error responses. The response may not include a JSON body. InternalServerError: description: The service had an unexpected error (`SERVER_ERROR`). content: diff --git a/specs/privacy-exclusions.yaml b/specs/privacy-exclusions.yaml index 2ab5812..da9dc28 100644 --- a/specs/privacy-exclusions.yaml +++ b/specs/privacy-exclusions.yaml @@ -67,6 +67,8 @@ paths: $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" + "429": + $ref: "#/components/responses/TooManyRequests" "500": $ref: "#/components/responses/InternalServerError" "503": @@ -188,6 +190,10 @@ components: example: code: PERMISSION_REQUIRED error: You do not have permission to use the service. + TooManyRequests: + description: >- + MaxMind rate-limited the request, usually because of excessive earlier + error responses. The response may not include a JSON body. InternalServerError: description: >- The service had an unexpected error (`SERVER_ERROR`). From 665986328a12b06bce5e4dd5c38e7547b6729b1b Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:41:11 +0000 Subject: [PATCH 20/31] Describe geofeed report rate limiting --- bundled/downloads.yaml | 6 ++++++ specs/downloads.yaml | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/bundled/downloads.yaml b/bundled/downloads.yaml index 0517a33..c494ed0 100644 --- a/bundled/downloads.yaml +++ b/bundled/downloads.yaml @@ -135,6 +135,8 @@ paths: $ref: '#/components/responses/GeofeedForbidden' '404': $ref: '#/components/responses/GeofeedNotFound' + '429': + $ref: '#/components/responses/GeofeedTooManyRequests' '500': $ref: '#/components/responses/GeofeedInternalServerError' '503': @@ -164,6 +166,8 @@ paths: $ref: '#/components/responses/GeofeedForbidden' '404': $ref: '#/components/responses/GeofeedNotFound' + '429': + $ref: '#/components/responses/GeofeedTooManyRequests' '500': $ref: '#/components/responses/GeofeedInternalServerError' '503': @@ -323,6 +327,8 @@ components: example: code: REPORT_NOT_FOUND error: Report not found with the given date. + GeofeedTooManyRequests: + description: MaxMind rate-limited the request, usually because of excessive earlier error responses. The response may not include a JSON body. GeofeedInternalServerError: description: The service had an unexpected error (`SERVER_ERROR`). content: diff --git a/specs/downloads.yaml b/specs/downloads.yaml index 253b8ea..764d66b 100644 --- a/specs/downloads.yaml +++ b/specs/downloads.yaml @@ -168,6 +168,8 @@ paths: $ref: "#/components/responses/GeofeedForbidden" "404": $ref: "#/components/responses/GeofeedNotFound" + "429": + $ref: "#/components/responses/GeofeedTooManyRequests" "500": $ref: "#/components/responses/GeofeedInternalServerError" "503": @@ -205,6 +207,8 @@ paths: $ref: "#/components/responses/GeofeedForbidden" "404": $ref: "#/components/responses/GeofeedNotFound" + "429": + $ref: "#/components/responses/GeofeedTooManyRequests" "500": $ref: "#/components/responses/GeofeedInternalServerError" "503": @@ -426,6 +430,10 @@ components: example: code: REPORT_NOT_FOUND error: Report not found with the given date. + GeofeedTooManyRequests: + description: >- + MaxMind rate-limited the request, usually because of excessive earlier + error responses. The response may not include a JSON body. GeofeedInternalServerError: description: >- The service had an unexpected error (`SERVER_ERROR`). From 9313deeb4083604df1d52ab1c137ab9b52d8e9c1 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:41:18 +0000 Subject: [PATCH 21/31] Describe both causes of download rate limits --- bundled/downloads.yaml | 2 +- specs/downloads.yaml | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/bundled/downloads.yaml b/bundled/downloads.yaml index c494ed0..abd150a 100644 --- a/bundled/downloads.yaml +++ b/bundled/downloads.yaml @@ -275,7 +275,7 @@ components: DownloadNotFound: description: No file matches the edition ID, date, and suffix, or the path does not match a download URL. The response does not have a JSON body, for example `Database edition "" not found`. DownloadTooManyRequests: - description: The account reached its download limit for a 24-hour period. The response does not have a JSON body. + description: The account reached its download limit for a 24-hour period, or MaxMind rate-limited the request, for example after excessive error responses. The response may not include a JSON body. DownloadLegalReasons: description: MaxMind cannot provide this download for legal reasons. The response does not have a JSON body, for example `Downloads are forbidden from countries and territories on the US embargo list` or `Downloads of this database from are forbidden due to US bulk sensitive data transfer rules`. DownloadInternalServerError: diff --git a/specs/downloads.yaml b/specs/downloads.yaml index 764d66b..72dab46 100644 --- a/specs/downloads.yaml +++ b/specs/downloads.yaml @@ -354,8 +354,9 @@ components: example `Database edition "" not found`. DownloadTooManyRequests: description: >- - The account reached its download limit for a 24-hour period. The - response does not have a JSON body. + The account reached its download limit for a 24-hour period, or MaxMind + rate-limited the request, for example after excessive error responses. + The response may not include a JSON body. DownloadLegalReasons: description: >- MaxMind cannot provide this download for legal reasons. The response From bfbdc68deb8394dddf6e63ef017cd1d0f1b9390b Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:42:28 +0000 Subject: [PATCH 22/31] Use generic Basic authentication descriptions --- bundled/geoip.yaml | 2 +- bundled/minfraud.yaml | 2 +- specs/geoip.yaml | 2 +- specs/minfraud.yaml | 3 +-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/bundled/geoip.yaml b/bundled/geoip.yaml index 6967885..6061bc0 100644 --- a/bundled/geoip.yaml +++ b/bundled/geoip.yaml @@ -199,7 +199,7 @@ components: - `LICENSE_KEY_REQUIRED`: the Basic credentials have no license key. headers: WWW-Authenticate: - description: The authentication scheme, `Basic realm="geoip2"`. + description: HTTP Basic authentication. schema: type: string content: diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index 33d8915..0d65c81 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -450,7 +450,7 @@ components: - `LICENSE_KEY_REQUIRED`: the Basic credentials have no license key. headers: WWW-Authenticate: - description: The authentication scheme, for example `Basic realm="minfraud"`. + description: HTTP Basic authentication. schema: type: string content: diff --git a/specs/geoip.yaml b/specs/geoip.yaml index 1434229..7927521 100644 --- a/specs/geoip.yaml +++ b/specs/geoip.yaml @@ -245,7 +245,7 @@ components: - `LICENSE_KEY_REQUIRED`: the Basic credentials have no license key. headers: WWW-Authenticate: - description: The authentication scheme, `Basic realm="geoip2"`. + description: HTTP Basic authentication. schema: type: string content: diff --git a/specs/minfraud.yaml b/specs/minfraud.yaml index c68063b..44872a8 100644 --- a/specs/minfraud.yaml +++ b/specs/minfraud.yaml @@ -535,8 +535,7 @@ components: - `LICENSE_KEY_REQUIRED`: the Basic credentials have no license key. headers: WWW-Authenticate: - description: >- - The authentication scheme, for example `Basic realm="minfraud"`. + description: HTTP Basic authentication. schema: type: string content: From eb08fa31899294a70c572918e82e2a89bc51fab9 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:42:31 +0000 Subject: [PATCH 23/31] Limit HTTP error body claims to documented APIs --- bundled/downloads.yaml | 2 +- bundled/license-key-validation.yaml | 2 +- bundled/privacy-exclusions.yaml | 2 +- specs/downloads.yaml | 2 +- specs/license-key-validation.yaml | 3 +-- specs/privacy-exclusions.yaml | 2 +- 6 files changed, 6 insertions(+), 7 deletions(-) diff --git a/bundled/downloads.yaml b/bundled/downloads.yaml index abd150a..12e044b 100644 --- a/bundled/downloads.yaml +++ b/bundled/downloads.yaml @@ -292,7 +292,7 @@ components: code: GEOFEED_ID_INVALID error: '''abc'' is not a valid geofeed_id.' GeofeedForbidden: - description: The account does not have permission to download this kind of report (`PERMISSION_REQUIRED`). A request that uses HTTP instead of HTTPS also gets this status, but without a JSON body. + description: The account does not have permission to download this kind of report (`PERMISSION_REQUIRED`). A request that uses HTTP instead of HTTPS also gets this status. content: application/vnd.maxmind.com-error+json: schema: diff --git a/bundled/license-key-validation.yaml b/bundled/license-key-validation.yaml index c68b841..0163011 100644 --- a/bundled/license-key-validation.yaml +++ b/bundled/license-key-validation.yaml @@ -89,7 +89,7 @@ components: code: AUTHORIZATION_INVALID error: Your account ID or license key could not be authenticated. Forbidden: - description: The account that owns the license key does not have permission to use this service (`PERMISSION_REQUIRED`). This response means that MaxMind recognizes the key. An unknown key gets a 401 response instead. A request that uses HTTP instead of HTTPS also gets this status, but without a JSON body. + description: The account that owns the license key does not have permission to use this service (`PERMISSION_REQUIRED`). This response means that MaxMind recognizes the key. An unknown key gets a 401 response instead. A request that uses HTTP instead of HTTPS also gets this status. content: application/json: schema: diff --git a/bundled/privacy-exclusions.yaml b/bundled/privacy-exclusions.yaml index 2cd0279..93cedcb 100644 --- a/bundled/privacy-exclusions.yaml +++ b/bundled/privacy-exclusions.yaml @@ -160,7 +160,7 @@ components: code: ACCOUNT_ID_REQUIRED error: An account ID and license key are required to use this service. Forbidden: - description: The account does not have permission to use this service (`PERMISSION_REQUIRED`). A request that uses HTTP instead of HTTPS also gets this status, but without a JSON body. + description: The account does not have permission to use this service (`PERMISSION_REQUIRED`). A request that uses HTTP instead of HTTPS also gets this status. content: application/vnd.maxmind.com-error+json: schema: diff --git a/specs/downloads.yaml b/specs/downloads.yaml index 72dab46..0e12a31 100644 --- a/specs/downloads.yaml +++ b/specs/downloads.yaml @@ -388,7 +388,7 @@ components: description: >- The account does not have permission to download this kind of report (`PERMISSION_REQUIRED`). A request that uses HTTP instead of HTTPS also - gets this status, but without a JSON body. + gets this status. content: application/vnd.maxmind.com-error+json: schema: diff --git a/specs/license-key-validation.yaml b/specs/license-key-validation.yaml index a896dbf..9872e13 100644 --- a/specs/license-key-validation.yaml +++ b/specs/license-key-validation.yaml @@ -111,8 +111,7 @@ components: The account that owns the license key does not have permission to use this service (`PERMISSION_REQUIRED`). This response means that MaxMind recognizes the key. An unknown key gets a 401 response instead. A - request that uses HTTP instead of HTTPS also gets this status, but - without a JSON body. + request that uses HTTP instead of HTTPS also gets this status. content: application/json: schema: diff --git a/specs/privacy-exclusions.yaml b/specs/privacy-exclusions.yaml index da9dc28..4ebc7a2 100644 --- a/specs/privacy-exclusions.yaml +++ b/specs/privacy-exclusions.yaml @@ -182,7 +182,7 @@ components: description: >- The account does not have permission to use this service (`PERMISSION_REQUIRED`). A request that uses HTTP instead of HTTPS also - gets this status, but without a JSON body. + gets this status. content: application/vnd.maxmind.com-error+json: schema: From 85c504e5015704e8fbad81c13f1fa4df9d50a586 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:42:34 +0000 Subject: [PATCH 24/31] Remove server email normalization promises --- bundled/minfraud.yaml | 4 ++-- components/minfraud-request.yaml | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index 0d65c81..f450ac9 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -649,11 +649,11 @@ components: address: type: string maxLength: 255 - description: The email address, or the MD5 hash of the normalized email address. Normalize the address before you hash it. See https://dev.maxmind.com/minfraud/normalizing-email-addresses-for-minfraud. A plaintext address must be a valid email address. MaxMind lowercases it, converts an internationalized domain to ASCII, and fixes a few common typos, such as a misspelled `gmail.com`. + description: The email address, or the MD5 hash of the normalized email address. Normalize the address before you hash it. See https://dev.maxmind.com/minfraud/normalizing-email-addresses-for-minfraud. A plaintext address must be a valid email address. domain: type: string maxLength: 255 - description: The domain of the email address. Do not include the `@`. You do not need to send this field unless you send the email address as an MD5 hash. MaxMind lowercases the domain, converts an internationalized domain to ASCII, and fixes a few common typos. + description: The domain of the email address. Do not include the `@`. You do not need to send this field unless you send the email address as an MD5 hash. Event: type: object properties: diff --git a/components/minfraud-request.yaml b/components/minfraud-request.yaml index fb4ad43..b7a1848 100644 --- a/components/minfraud-request.yaml +++ b/components/minfraud-request.yaml @@ -198,17 +198,14 @@ schemas: The email address, or the MD5 hash of the normalized email address. Normalize the address before you hash it. See https://dev.maxmind.com/minfraud/normalizing-email-addresses-for-minfraud. - A plaintext address must be a valid email address. MaxMind lowercases - it, converts an internationalized domain to ASCII, and fixes a few - common typos, such as a misspelled `gmail.com`. + A plaintext address must be a valid email address. domain: type: string maxLength: 255 description: >- The domain of the email address. Do not include the `@`. You do not need to send this field unless you send the email address as an MD5 - hash. MaxMind lowercases the domain, converts an internationalized - domain to ASCII, and fixes a few common typos. + hash. Address: type: object description: A billing or shipping address. From a26e7b24e31395fa593a2bef8595b1ea967f2939 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:42:38 +0000 Subject: [PATCH 25/31] Remove the webhook acknowledgement claim --- bundled/minfraud.yaml | 2 +- specs/minfraud.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index f450ac9..f3071e5 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -376,7 +376,7 @@ webhooks: format: date-time responses: 2XX: - description: Return a 2xx status to acknowledge the alert. + description: The receiving endpoint returned a successful HTTP status. components: securitySchemes: basicAuth: diff --git a/specs/minfraud.yaml b/specs/minfraud.yaml index 44872a8..49d88dc 100644 --- a/specs/minfraud.yaml +++ b/specs/minfraud.yaml @@ -427,7 +427,7 @@ webhooks: format: date-time responses: "2XX": - description: Return a 2xx status to acknowledge the alert. + description: The receiving endpoint returned a successful HTTP status. components: securitySchemes: basicAuth: From 795c76f44d51a53952e4d8df0604502cba60df3f Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:42:41 +0000 Subject: [PATCH 26/31] Remove the cursor precision guarantee --- bundled/minfraud.yaml | 2 +- components/minfraud-response.yaml | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index f3071e5..d0c81d1 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -1878,7 +1878,7 @@ components: last_update_timestamp: type: string format: date-time - description: The sort timestamp of the last transaction in `updates`, in RFC 3339 format with microsecond precision. This can differ from that transaction's `action_last_updated` and `note_last_updated`. Pass this value as `updates_after` in your next request. An empty `updates` array means there are no updates after `updates_after` yet. This value is then not a transaction's timestamp, so keep your current `updates_after` for the next request. + description: The sort timestamp of the last transaction in `updates`, in RFC 3339 format. This can differ from that transaction's `action_last_updated` and `note_last_updated`. Pass this value as `updates_after` in your next request. An empty `updates` array means there are no updates after `updates_after` yet. This value is then not a transaction's timestamp, so keep your current `updates_after` for the next request. updates: type: array description: The transactions with a disposition or note update after `updates_after`, including a transaction whose manual review period expired. MaxMind sorts in ascending order by the earliest update timestamp, either the disposition or the note, after `updates_after`. A response usually holds at most 1000 updated transactions. Do not rely on this limit. A transaction can appear in more than one response, for example when its note changes after its disposition, so process updates idempotently. diff --git a/components/minfraud-response.yaml b/components/minfraud-response.yaml index 2bf1ec1..4ef885a 100644 --- a/components/minfraud-response.yaml +++ b/components/minfraud-response.yaml @@ -652,12 +652,11 @@ schemas: format: date-time description: >- The sort timestamp of the last transaction in `updates`, in RFC 3339 - format with microsecond precision. This can differ from that - transaction's `action_last_updated` and `note_last_updated`. Pass this - value as `updates_after` in your next request. An empty `updates` - array means there are no updates after `updates_after` yet. This value - is then not a transaction's timestamp, so keep your current - `updates_after` for the next request. + format. This can differ from that transaction's `action_last_updated` + and `note_last_updated`. Pass this value as `updates_after` in your + next request. An empty `updates` array means there are no updates + after `updates_after` yet. This value is then not a transaction's + timestamp, so keep your current `updates_after` for the next request. updates: type: array description: >- From fb9cdb15d05dab3a1619340f8c9993e33e088899 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:42:44 +0000 Subject: [PATCH 27/31] Document the transaction report body limit --- bundled/minfraud.yaml | 2 +- specs/minfraud.yaml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index d0c81d1..225b669 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -485,7 +485,7 @@ components: ScorePayloadTooLarge: description: The request body is larger than 20,000 bytes. The response does not have a JSON body. ReportPayloadTooLarge: - description: The request body is too large. The response does not have a JSON body. + description: The request body is larger than 65,536 bytes. The response does not have a JSON body. TooManyRequests: description: MaxMind rate-limited the request, usually because of too many earlier error responses. The response may have no body. InternalServerError: diff --git a/specs/minfraud.yaml b/specs/minfraud.yaml index 49d88dc..86022d6 100644 --- a/specs/minfraud.yaml +++ b/specs/minfraud.yaml @@ -578,7 +578,8 @@ components: a JSON body. ReportPayloadTooLarge: description: >- - The request body is too large. The response does not have a JSON body. + The request body is larger than 65,536 bytes. The response does not have + a JSON body. TooManyRequests: description: >- MaxMind rate-limited the request, usually because of too many earlier From ce17682aa92bdc83b42f79483cc2c62e0803867c Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:42:47 +0000 Subject: [PATCH 28/31] Document the license validation body limit --- bundled/license-key-validation.yaml | 2 +- specs/license-key-validation.yaml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bundled/license-key-validation.yaml b/bundled/license-key-validation.yaml index 0163011..6c48cce 100644 --- a/bundled/license-key-validation.yaml +++ b/bundled/license-key-validation.yaml @@ -98,7 +98,7 @@ components: code: PERMISSION_REQUIRED error: You do not have permission to use this service interface. PayloadTooLarge: - description: The request body is too large. The response does not have a JSON body. + description: The request body is larger than 65,536 bytes. The response does not have a JSON body. InternalServerError: description: The service had an unexpected error (`SERVER_ERROR`). content: diff --git a/specs/license-key-validation.yaml b/specs/license-key-validation.yaml index 9872e13..cfd0e77 100644 --- a/specs/license-key-validation.yaml +++ b/specs/license-key-validation.yaml @@ -121,7 +121,8 @@ components: error: You do not have permission to use this service interface. PayloadTooLarge: description: >- - The request body is too large. The response does not have a JSON body. + The request body is larger than 65,536 bytes. The response does not have + a JSON body. InternalServerError: description: >- The service had an unexpected error (`SERVER_ERROR`). From f91065945314552b73ea326d8bdff1e3b3121fd3 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:42:50 +0000 Subject: [PATCH 29/31] Describe NUL restrictions on report fields --- bundled/minfraud.yaml | 6 +++--- components/minfraud-request.yaml | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/bundled/minfraud.yaml b/bundled/minfraud.yaml index 225b669..ebfa7fc 100644 --- a/bundled/minfraud.yaml +++ b/bundled/minfraud.yaml @@ -1794,7 +1794,7 @@ components: properties: chargeback_code: type: string - description: The reason code your payment processor gives for a chargeback. + description: The reason code your payment processor gives for a chargeback. It must not contain a NUL character. ip_address: type: string anyOf: @@ -1812,7 +1812,7 @@ components: notes: type: string maxLength: 1000 - description: Your notes on the tag for this transaction. + description: Your notes on the tag for this transaction. It must not contain a NUL character. tag: type: string enum: @@ -1832,7 +1832,7 @@ components: transaction_id: type: string minLength: 1 - description: The transaction ID you gave in the original minFraud request. + description: The transaction ID you gave in the original minFraud request. It must not contain a NUL character. DispositionUpdate: type: object required: diff --git a/components/minfraud-request.yaml b/components/minfraud-request.yaml index b7a1848..36b3f8e 100644 --- a/components/minfraud-request.yaml +++ b/components/minfraud-request.yaml @@ -678,7 +678,8 @@ schemas: chargeback_code: type: string description: >- - The reason code your payment processor gives for a chargeback. + The reason code your payment processor gives for a chargeback. It must + not contain a NUL character. ip_address: type: string anyOf: @@ -702,7 +703,9 @@ schemas: notes: type: string maxLength: 1000 - description: Your notes on the tag for this transaction. + description: >- + Your notes on the tag for this transaction. It must not contain a NUL + character. tag: type: string enum: @@ -729,5 +732,6 @@ schemas: transaction_id: type: string minLength: 1 - description: - The transaction ID you gave in the original minFraud request. + description: >- + The transaction ID you gave in the original minFraud request. It must + not contain a NUL character. From 7cbe1f9c6214962fec6798f39d20f637c8c148b5 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:42:53 +0000 Subject: [PATCH 30/31] Describe IPv6 forms of privacy exclusions --- bundled/privacy-exclusions.yaml | 2 +- specs/privacy-exclusions.yaml | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/bundled/privacy-exclusions.yaml b/bundled/privacy-exclusions.yaml index 93cedcb..88ba48a 100644 --- a/bundled/privacy-exclusions.yaml +++ b/bundled/privacy-exclusions.yaml @@ -111,7 +111,7 @@ components: properties: exclusions: type: array - description: The current privacy exclusions. Empty if there are none. + description: 'The current privacy exclusions. Empty if there are none. Each IPv4 network appears three times: as the IPv4 network, as the IPv4-mapped IPv6 network in `::ffff:0:0/96`, and as the 6to4 IPv6 network in `2002::/16`. Exclude all three forms.' items: $ref: '#/components/schemas/Exclusion' Error: diff --git a/specs/privacy-exclusions.yaml b/specs/privacy-exclusions.yaml index 4ebc7a2..11fe46b 100644 --- a/specs/privacy-exclusions.yaml +++ b/specs/privacy-exclusions.yaml @@ -140,7 +140,10 @@ components: exclusions: type: array description: >- - The current privacy exclusions. Empty if there are none. + The current privacy exclusions. Empty if there are none. Each IPv4 + network appears three times: as the IPv4 network, as the IPv4-mapped + IPv6 network in `::ffff:0:0/96`, and as the 6to4 IPv6 network in + `2002::/16`. Exclude all three forms. items: $ref: "#/components/schemas/Exclusion" responses: From ad00cdab94ce51295998af18b92e26e89ae4ecc4 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Thu, 24 Sep 2026 20:57:01 +0000 Subject: [PATCH 31/31] Revert "Remove the undocumented GeoIP service error" This reverts commit f6a8da58186e2d26b0fa50d8efe58f84b522dd11. SERVICE_INVALID is returned for unsupported services and is now being documented on the dev site. --- bundled/geoip.yaml | 1 + specs/geoip.yaml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/bundled/geoip.yaml b/bundled/geoip.yaml index 6061bc0..00d7447 100644 --- a/bundled/geoip.yaml +++ b/bundled/geoip.yaml @@ -184,6 +184,7 @@ components: - `IP_ADDRESS_REQUIRED`: the request has an empty IP address. - `IP_ADDRESS_INVALID`: the IP address is not a valid IPv4 or IPv6 address. - `IP_ADDRESS_RESERVED`: the IP address is in a reserved or private range. + - `SERVICE_INVALID`: the service is not available on this host. On `geolite.info`, only Country and City are available. content: application/vnd.maxmind.com-error+json: schema: diff --git a/specs/geoip.yaml b/specs/geoip.yaml index 7927521..d272c1b 100644 --- a/specs/geoip.yaml +++ b/specs/geoip.yaml @@ -225,6 +225,9 @@ components: - `IP_ADDRESS_RESERVED`: the IP address is in a reserved or private range. + + - `SERVICE_INVALID`: the service is not available on this host. On + `geolite.info`, only Country and City are available. content: application/vnd.maxmind.com-error+json: schema: