Skip to content

Commit 0921c55

Browse files
mja00zlataovce
andauthored
feat: update docs to fill v3 (#614)
* feat: update docs to fill v3 * feat: update api calls to use fill * fix: handle bad version being passed * refactor: touch-ups * style: reorganize paragraphs --------- Co-authored-by: Matouš Kučera <[email protected]>
1 parent 08fa5aa commit 0921c55

File tree

2 files changed

+165
-25
lines changed

2 files changed

+165
-25
lines changed

src/content/docs/misc/downloads-api.mdx

Lines changed: 150 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,45 +5,60 @@ slug: misc/downloads-api
55
---
66

77
PaperMC provides a downloads API to facilitate automated downloads access. Full documentation can be
8-
found on the [Downloads API Docs](https://api.papermc.io/docs).
8+
found on the [Downloads API Docs](https://fill.papermc.io/swagger-ui/index.html#/).
99

1010
:::danger
1111

1212
We emphatically **do not recommend** using unstable builds or auto-updaters within production environments.
1313

1414
:::
1515

16+
All requests must now include a valid User-Agent header that:
17+
- Clearly identifies your software or company
18+
- Is not generic (e.g. curl, wget, or similar defaults)
19+
- Includes a contact URL or email address (e.g. a homepage, bot info page, or support email)
20+
21+
**Some examples:**
22+
```
23+
mc-image-helper/1.39.11 (https://github.com/itzg/docker-minecraft-server)
24+
nodecraft/packifier/1.0.0 ([email protected])
25+
```
26+
27+
## REST API examples
28+
1629
:::note
1730

1831
We require `jq` to be installed for the examples below. You can install it with `sudo apt-get install jq` on Debian/Ubuntu.
1932

2033
:::
2134

22-
## Getting the latest version
35+
### Getting the latest version
2336

2437
```shell
2538
#!/usr/bin/env sh
2639

2740
PROJECT="paper"
41+
USER_AGENT="cool-project/1.0.0 ([email protected])"
2842

29-
LATEST_VERSION=$(curl -s https://api.papermc.io/v2/projects/${PROJECT} | \
30-
jq -r '.versions[-1]')
43+
LATEST_VERSION=$(curl -s -H "User-Agent: $USER_AGENT" https://fill.papermc.io/v3/projects/${PROJECT} | \
44+
jq -r '.versions | to_entries[0] | .value[0]')
3145

3246
echo "Latest version is $LATEST_VERSION"
3347
```
3448

3549
This will get the latest available Minecraft version for the given project.
3650

37-
## Getting the latest stable build number
51+
### Getting the latest stable build number
3852

3953
```shell replace
4054
#!/usr/bin/env sh
4155

4256
PROJECT="paper"
4357
MINECRAFT_VERSION="\{LATEST_PAPER_RELEASE}"
58+
USER_AGENT="cool-project/1.0.0 ([email protected])"
4459

45-
LATEST_BUILD=$(curl -s https://api.papermc.io/v2/projects/${PROJECT}/versions/${MINECRAFT_VERSION}/builds | \
46-
jq '.builds | map(select(.channel == "default") | .build) | .[-1]')
60+
LATEST_BUILD=$(curl -s -H "User-Agent: $USER_AGENT" https://fill.papermc.io/v3/projects/${PROJECT}/versions/${MINECRAFT_VERSION}/builds | \
61+
jq -r 'map(select(.channel == "STABLE")) | .[0] | .id')
4762

4863
if [ "$LATEST_BUILD" != "null" ]; then
4964
echo "Latest stable build is $LATEST_BUILD"
@@ -54,21 +69,30 @@ fi
5469

5570
This will get the latest stable build for the given project and Minecraft version, if it's available.
5671

57-
## Downloading the latest stable build
72+
### Downloading the latest stable build
5873

5974
```shell replace
6075
#!/usr/bin/env sh
6176

6277
PROJECT="paper"
6378
MINECRAFT_VERSION="\{LATEST_PAPER_RELEASE}"
79+
USER_AGENT="cool-project/1.0.0 ([email protected])"
6480

65-
LATEST_BUILD=$(curl -s https://api.papermc.io/v2/projects/${PROJECT}/versions/${MINECRAFT_VERSION}/builds | \
66-
jq -r '.builds | map(select(.channel == "default") | .build) | .[-1]')
81+
# First check if the version exists
82+
VERSION_CHECK=$(curl -s -H "User-Agent: $USER_AGENT" https://fill.papermc.io/v3/projects/${PROJECT}/versions/${MINECRAFT_VERSION}/builds)
6783

68-
if [ "$LATEST_BUILD" != "null" ]; then
69-
JAR_NAME=${PROJECT}-${MINECRAFT_VERSION}-${LATEST_BUILD}.jar
70-
PAPERMC_URL="https://api.papermc.io/v2/projects/${PROJECT}/versions/${MINECRAFT_VERSION}/builds/${LATEST_BUILD}/downloads/${JAR_NAME}"
84+
# Check if the API returned an error
85+
if echo "$VERSION_CHECK" | jq -e '.ok == false' > /dev/null 2>&1; then
86+
ERROR_MSG=$(echo "$VERSION_CHECK" | jq -r '.message // "Unknown error"')
87+
echo "Error: $ERROR_MSG"
88+
exit 1
89+
fi
90+
91+
# Get the download URL directly, or null if no stable build exists
92+
PAPERMC_URL=$(curl -s -H "User-Agent: $USER_AGENT" https://fill.papermc.io/v3/projects/${PROJECT}/versions/${MINECRAFT_VERSION}/builds | \
93+
jq -r 'first(.[] | select(.channel == "STABLE") | .downloads."server:default".url) // "null"')
7194

95+
if [ "$PAPERMC_URL" != "null" ]; then
7296
# Download the latest Paper version
7397
curl -o server.jar $PAPERMC_URL
7498
echo "Download completed"
@@ -80,3 +104,116 @@ fi
80104
This is the most common use case for the API. It will download the latest stable build for the given project and
81105
Minecraft version. You should always serve & use the stable builds. Experimental builds are prone to error and
82106
do not receive support.
107+
108+
## GraphQL API examples
109+
110+
Fill also supports a GraphQL API, which can be accessed at `https://fill.papermc.io/graphql`.
111+
112+
A built-in GraphQL playground is available at https://fill.papermc.io/graphiql?path=/graphql.
113+
Common API tools such as Postman will introspect the API and provide a UI for building queries.
114+
115+
### Getting the latest version
116+
```graphql
117+
query LatestVersion {
118+
project(id: "paper") {
119+
versions(last: 1) {
120+
id
121+
}
122+
}
123+
}
124+
```
125+
126+
<details>
127+
<summary>Example response</summary>
128+
129+
```json
130+
{
131+
"data": {
132+
"project": {
133+
"versions": [
134+
{
135+
"id": "1.21.6"
136+
}
137+
]
138+
}
139+
}
140+
}
141+
```
142+
143+
</details>
144+
145+
### Getting the latest stable build number
146+
```graphql
147+
query LatestStableBuild {
148+
project(id: "paper") {
149+
versions(last: 1) {
150+
builds(filterBy: { channel: STABLE }, last: 1) {
151+
id
152+
}
153+
}
154+
}
155+
}
156+
```
157+
158+
<details>
159+
<summary>Example response</summary>
160+
161+
```json
162+
{
163+
"data": {
164+
"project": {
165+
"versions": [
166+
{
167+
"builds": [
168+
{
169+
"id": 46
170+
}
171+
]
172+
}
173+
]
174+
}
175+
}
176+
}
177+
```
178+
179+
</details>
180+
181+
### Getting the latest stable build download URL
182+
```graphql
183+
query LatestStableBuildDownloadURL {
184+
project(id: "paper") {
185+
versions(last: 1) {
186+
builds(filterBy: { channel: STABLE }, last: 1) {
187+
download(name: "server:default") {
188+
url
189+
}
190+
}
191+
}
192+
}
193+
}
194+
```
195+
196+
<details>
197+
<summary>Example response</summary>
198+
199+
```json
200+
{
201+
"data": {
202+
"project": {
203+
"versions": [
204+
{
205+
"builds": [
206+
{
207+
"download": {
208+
"url": "https://fill-data.papermc.io/v1/objects/bfca155b4a6b45644bfc1766f4e02a83c736e45fcc060e8788c71d6e7b3d56f6/paper-1.21.6-46.jar"
209+
}
210+
}
211+
]
212+
}
213+
]
214+
}
215+
}
216+
}
217+
```
218+
219+
</details>

src/utils/versions.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,30 @@ const manifest: Manifest = await fetch("https://piston-meta.mojang.com/mc/game/v
2424
export const LATEST_MC_RELEASE = manifest.latest.release;
2525

2626
interface Project {
27-
project_id: string;
28-
project_name: string;
29-
version_groups: string[];
30-
versions: string[];
27+
versions: Record<string, string[]>;
3128
}
3229

33-
const paperProject: Project = await fetch("https://api.papermc.io/v2/projects/paper").then((r) => r.json());
30+
const fetchFillVersions = async (id: string): Promise<string[]> => {
31+
const project: Project = await fetch(`https://fill.papermc.io/v3/projects/${id}`).then((r) => r.json());
3432

35-
export const LATEST_PAPER_RELEASE = paperProject.versions[paperProject.versions.length - 1];
33+
return Object.values(project.versions).flat();
34+
};
3635

37-
const velocityProject: Project = await fetch("https://api.papermc.io/v2/projects/velocity").then((r) => r.json());
36+
const paperVersions = await fetchFillVersions("paper");
3837

39-
export const LATEST_VELOCITY_RELEASE = velocityProject.versions[velocityProject.versions.length - 1];
38+
export const LATEST_PAPER_RELEASE = paperVersions[0];
4039

41-
const foliaProject: Project = await fetch("https://api.papermc.io/v2/projects/folia").then((r) => r.json());
40+
const velocityVersions = await fetchFillVersions("velocity");
4241

43-
export const LATEST_FOLIA_RELEASE = foliaProject.versions[foliaProject.versions.length - 1];
42+
export const LATEST_VELOCITY_RELEASE = velocityVersions[0];
4443

45-
const waterfallProject: Project = await fetch("https://api.papermc.io/v2/projects/waterfall").then((r) => r.json());
44+
const foliaVersions = await fetchFillVersions("folia");
4645

47-
export const LATEST_WATERFALL_RELEASE = waterfallProject.versions[waterfallProject.versions.length - 1];
46+
export const LATEST_FOLIA_RELEASE = foliaVersions[0];
47+
48+
const waterfallVersions = await fetchFillVersions("waterfall");
49+
50+
export const LATEST_WATERFALL_RELEASE = waterfallVersions[0];
4851

4952
interface Tag {
5053
name: string;

0 commit comments

Comments
 (0)