AppApiFile adds the /file endpoint to the AppApi routes definition. Makes it possible to query files via the api.
| ProcessWire-Module: | https://processwire.com/modules/app-api-file/ |
| Support-Forum: | https://processwire.com/talk/topic/26272-appapi-module-appapifile/ |
| Repository: | https://github.com/Sebiworld/AppApiFile |
Relies on AppApi:
| AppApi-Module: | https://processwire.com/modules/app-api/ |
| Support-Forum: | https://processwire.com/talk/topic/24014-new-module-appapi/ |
| Repository: | https://github.com/Sebiworld/AppApi |
| AppApi Wiki: | https://github.com/Sebiworld/AppApi/wiki |
Installation
AppApiFile relies on the base module AppApi, which must be installed before AppApiFile can do its work.
AppApi and AppApiFile can be installed like every other module in ProcessWire. Check the following guide for detailed information: How-To Install or Uninstall Modules
The prerequisites are PHP>=7.2.0 and a ProcessWire version >=3.93.0 (+ AppApi>=1.2.0). However, this is also checked during the installation of the module. No further dependencies.
Features
You can access all files that are uploaded at any ProcessWire page. Call /file/route/in/pagetree?file=test.jpg to access a page via its route in the page tree. Alternatively you can call /file/4242?file=test.jpg (e.g.,) to access a page by its id. The module will make sure that the page is accessible by the active user.
The GET-param "file" defines the basename of the file which you want to get.
The following GET-params (optional) can be used to manipulate an image:
| Param | Value | Description |
|---|---|---|
| width | int >= 0 | Width of the requested image |
| height | int >= 0 | Height of the requested image |
| maxwidth | int >= 0 | Maximum Width, if the original image's resolution is sufficient |
| maxheight | int >= 0 | Maximum Height, if the original image's resolution is sufficient |
| cropx | int >= 0 | Start-X-position for cropping (crop enabled, if width, height, cropx & cropy set) |
| cropy | int >= 0 | Start-Y-position for cropping (crop enabled, if width, height, cropx & cropy set) |
Images are never scaled up. If only width or only height is larger than the original image, the original size is delivered. If width and height are both set and one of them is larger than the original, both are reduced by the same factor until the image fits into the original size, so the requested aspect ratio is kept (e.g. 300x800 for a 600x400 image gives 150x400). Requested sizes (width, height, maxwidth, maxheight) are limited to 4096 pixels per axis (AppApiFile::MAX_DIMENSION). Without size parameters the original file is delivered.
Use GET-Param format=base64 to receive the file in base64 format.
Caching
| Param | Value | Description |
|---|---|---|
| v | non-empty string | Version of the file, e.g. a hash of its modification time and size. Change it whenever the file changes. |
A page counts as public if $page->isPublic() is true (for repeater items: the page that owns the repeater). Access modules can make a page non-public, e.g. PageAccessReleasetime for pages with a release time.
| Request | v set | no v |
|---|---|---|
| Guest, public page | public, max-age=31536000, immutable | no-cache |
| Logged-in user, public page | private, max-age=31536000, immutable | private, no-cache |
| Non-public page (any user) | private, no-cache | private, no-cache |
The value of v does not change the response. Only guests get public, so shared caches never store a response that depended on a user's rights. Files of non-public pages are revalidated on every use, so access is checked every time.
A request whose If-None-Match header contains the current ETag (also as weak W/ ETag or in a list) is answered with 304 Not Modified and no body. This does not apply to format=base64: those responses are always sent in full and without the caching headers above.
Access
Files of a page that the current user cannot view (e.g. unpublished pages) are answered with 404 Not Found, the same as an unknown page.
Pro tip: If you want to include an image from the api using the standard <img src=""> tag, it can be very difficult to include the api key and a token as headers. However, it is possible to include these values as GET parameters. The GET parameter with the apikey is called api_key. A token can be sent as parameter authorization.
Disclaimer: I recommend to use this solution only for this exceptional case. Generally headers are the better and more elegant solution.
Changelog
Changes in 2.0.0 (2026-10-02)
Behavior changes
Check these before updating:
- Files of pages that the current user cannot view now return
404 Not Foundinstead of403 Forbidden, the same as an unknown page. - Images are no longer scaled up beyond their original size (
width/heightabove the original deliver the original size). - Requested image sizes are limited to 4096 pixels per axis.
- New caching headers:
Cache-Control: no-cache(guests, public pages withoutv) orprivate, …(logged-in users and non-public pages, see "Caching") instead ofpublic, must-revalidate, post-check=0, pre-check=0. The headersExpires: -1andPragma: publicare no longer sent.
New
- GET-param
v: versioned URLs of public pages are cached for a year (public, max-age=31536000, immutablefor guests,private, max-age=31536000, immutablefor logged-in users) If-None-Matchwith the current ETag is answered with304 Not Modified
Changes in 1.0.6 (2022-06-01)
- Bugfix throw 404 status if not found
Changes in 1.0.5 (2022-05-30)
- Fix Webp support
Changes in 1.0.4 (2022-04-29)
- Added support for Multi-Language URLS
Changes in 1.0.3 (2021-10-31)
- Improved access to repeater images
Changes in 1.0.2 (2021-10-23)
- Updated module infos
Changes in 1.0.1 (2021-10-23)
- Smaller improvements in README
Changes in 1.0.0 (2021-10-21)
- Added file endpoint
- implemented different ways to access a page
- implemented image-manipulation parameters
Versioning
We use SemVer for versioning. For the versions available, see the tags on this repository.
License
This project is licensed under the Mozilla Public License Version 2.0 - see the LICENSE.md file for details.
More modules by Sebi
- AppApiFile by Sebi
Page Access Releasetime
Enables you to set a start- and end-time for the release of pages. Prevents unreleased pages from being displayed.4PageAccessReleasetime by SebiAppApi - Page
AppApiPage adds the /page endpoint to the AppApi routes definition. Makes it possible to query pages via the api.3AppApiPage by Sebi
Install and use modules at your own risk. Always have a site and database backup before installing new modules.