My children’s school uses the 1Core Family app to share photos. The iOS app lets me save a photo at a time, but I could not find a bulk export in the app or the parent website. After a little investigation, I exported 5,502 photos and videos from three galleries and restored their available gallery dates.
This post documents the workflow while it is still fresh in my mind.
Only do this with your own account and media you are authorized to access. A Charles capture contains live authentication credentials. Do not upload the session, paste its headers into a website, check it into Git, or share it with anyone.
The screenshots below are tightly cropped and sanitized. They do not contain live tokens, signed URLs, family details, or device-specific network addresses.
My export at a glance
| File count | Download size | |
|---|---|---|
| Photos | 4,954 | 23.09 GB |
| Videos | 548 | 21.74 GB |
| Total | 5,502 | 44.84 GB |
The available gallery dates span just over three years, from July 3, 2023 through August 3, 2026.
Availability note (August 14, 2026): For my account, this workflow retrieved gallery media back to July 3, 2023, but no earlier. The app’s Activities and Timeline endpoints also returned no content before that date. This appears to be a limit of the media currently exposed by 1Core, not the downloader, and it may differ by account or change over time.
Why the web login was not enough
The parent website and iOS app use different authentication mechanisms. The web portal uses an ASP.NET browser session. The iOS gallery talks to api.1core.com and sends app-specific authorizationkey, applicationkey, and userid headers.
I did not find a gallery API call or token exchange in the signed-in web portal, so I captured one request from the iOS app and replayed that request locally. The authorization headers lasted much longer than the individual signed photo URLs, which expired after roughly 30 minutes.
What you need
- A Mac and iPhone on the same Wi-Fi network
- The current version of Charles Proxy
- The 1Core Family iOS app, signed in to your account
- Enough local disk space for the gallery
- My 1Core gallery tools, which read a private Charles session without printing the captured credentials and can apply fallback dates to a separate copy
- Optional: ExifTool for restoring dates after download
Use the latest Charles release. My first attempt used an old Intel-only build that could no longer complete the API’s modern TLS handshake.
A note about the trial: Charles is paid software with a free trial. In trial mode, startup may pause for about 10 seconds, and Charles may require a restart after roughly 30 minutes. That is still enough time to capture and save one gallery request; the downloader does not need Charles afterward, provided the captured authorization remains valid.
1. Start Charles without proxying the Mac
Launch Charles. It may offer to install its macOS proxy helper.

For this workflow, click Not Yet. The iPhone will be configured manually, and the Mac itself does not need to send its traffic through Charles. This also avoids leaving macOS pointed at a proxy that is no longer running when Charles quits.
Charles normally listens on port 8888. You can confirm this under Proxy → Proxy Settings.
2. Allow the iPhone to connect
Keep the Mac and iPhone on the same Wi-Fi network. Temporarily disable a VPN if it prevents devices on the local network from reaching one another.
In Charles, open Proxy → Access Control Settings. I left Prompt to allow unauthorized connections enabled and approved only my iPhone when it connected.

Do not add 0.0.0.0/0; that would allow any reachable device to use your proxy. If you prefer an explicit rule, add only the iPhone’s local IP address.
Find the Mac’s Wi-Fi IP address in System Settings → Network → Wi-Fi → Details → TCP/IP. It will usually look like 192.168.x.x or 10.x.x.x.
3. Point the iPhone at Charles
On the iPhone:
- Open Settings → Wi-Fi.
- Tap the information button beside the current network.
- Scroll to Configure Proxy.
- Choose Manual.
- Enter the Mac’s Wi-Fi IP as Server.
- Enter
8888as Port. - Leave authentication off and save.
Charles’s official iPhone instructions cover the same setup.
If Charles asks whether to allow a new connection, verify that the address matches the iPhone and approve it.
4. Install and trust the Charles certificate
The proxy can see encrypted API requests only if the iPhone trusts Charles’s temporary certificate authority.
- With the manual Wi-Fi proxy still enabled, open Safari on the iPhone.
- Visit https://chls.pro/ssl.
- Allow the configuration profile to download.
- Open Settings → General → VPN & Device Management and install the Charles profile.
- Open Settings → General → About → Certificate Trust Settings.
- Enable full trust for the Charles certificate.
These are also the steps in Charles’s official SSL certificate documentation.
If Safari says the server cannot be found, the iPhone is not reaching Charles. Recheck the Mac’s IP address, port 8888, Charles’s access-control prompt, the Wi-Fi network, macOS firewall settings, and any VPN.
5. Decrypt only the 1Core API
In Charles, open Proxy → SSL Proxying Settings:
- Enable SSL Proxying.
- Add one Include location.
- Set the host to
api.1core.comand the port to443.

Avoid a wildcard such as *. It captures far more private phone traffic than this job needs.
6. Capture one gallery request
Clear the current Charles session, make sure recording is active, and then:
- Open the 1Core Family app.
- Open the child’s Gallery.
- Pull down to refresh or open the newest photo.
- Return to Charles and filter for
1core.
A successful capture should contain api.1core.com; media downloads may also appear under content.1core.com.

Under api.1core.com, look for a successful POST request to:
/FamilyApp/GetChildIndividualGallery/
The request headers contain the three app credentials, and the JSON request body contains the center, family, and child identifiers. Do not copy any of those values into a blog post, issue, chat, or public script.
Save the Charles session to a private .chls file and stop recording. A safer downloader reads the required values directly from that file without printing them. If you inspect or copy the request manually, remember that command-line arguments and shell history are not good places for credentials.
7. Download the gallery page by page
The current request goes to:
https://api.1core.com/FamilyApp/GetChildIndividualGallery/
Download 1core-download.py from the gist, then run it with the private Charles session and a new output folder:
chmod 600 capture.chls
python3 1core-download.py capture.chls '1Core Gallery'
The script uses only Python’s standard library. It finds the newest successful gallery request in the capture, keeps its credentials in memory, and replays the captured JSON body page by page. It preserves the captured center, family, and child identifiers rather than relying on somebody else’s example IDs.
The API response includes records such as:
PhotoURL: a short-lived signed media URLPhotoName: the original server-side namePhotoDateTime: the gallery date and timeSysPhotoId: the 1Core media identifierIsNextPageEnabled: whether another page exists
Download each page’s media immediately before fetching too far ahead. The signed URLs expire, so a robust downloader should refetch the page when a media request returns 403, skip existing non-empty files when resuming, and write to a temporary .part file before renaming a completed download.
The downloader writes date-index.csv and manifest.json, skips existing non-empty files when resumed, and never writes the private headers or signed URLs into either manifest. On macOS and other POSIX systems, it also restricts the gallery folder and generated files to the current user. It was inspired by northnose’s original shell-script gist, updated for the current api.1core.com FamilyApp endpoint and Charles session format.
I saved a private manifest alongside each gallery with the filename, byte count, photo ID, and PhotoDateTime. That manifest became important for both restoring dates and auditing the transfer.
8. Restore photo dates
Many downloaded JPEGs had UUID-like filenames and no useful EXIF date. The API’s PhotoDateTime is the date 1Core uses to group the item in its gallery. It may be an upload or posting time rather than the moment the camera took the photo, so preserve any existing camera metadata and treat the gallery timestamp as a fallback.
Of the 5,502 exported records, 5,457 included PhotoDateTime. The remaining 45 were photos, which I left unchanged rather than guessing.
For files without an embedded capture date, I used that fallback to set:
DateTimeOriginalCreateDateModifyDate- the filesystem modification time
Download apply-1core-dates.py from the same gist, then give it the downloaded gallery and a new output folder:
python3 apply-1core-dates.py '1Core Gallery' '1Core Gallery dated'
The script copies the gallery first and modifies only the files in the new folder. For images, one ExifTool condition covers both the embedded fields and filesystem modification time, so a file that already has DateTimeOriginal is skipped completely. Videos receive equivalent QuickTime dates only when they lack an embedded creation date. The original downloads remain untouched.
By default, a gallery timestamp without an offset is interpreted in the Mac’s current timezone. If the gallery belongs in another timezone, pass an IANA name such as --timezone America/Los_Angeles. Validate a sample with exiftool '1Core Gallery dated/photo.jpg', and keep the untouched originals until the Photos import is verified. A handful of my JPEGs had malformed secondary-image pointers; working on a separate copy kept those failures recoverable.
9. Clean everything up
Do not leave the phone proxy or trusted certificate enabled after the capture.
- On the iPhone, return to Settings → Wi-Fi → Configure Proxy and choose Off.
- Remove the Charles profile under Settings → General → VPN & Device Management.
- Confirm the Charles certificate no longer appears under Certificate Trust Settings.
- Quit Charles.
- Re-enable your VPN if you disabled it.
- Delete the
.chlscapture, cached signed URLs, request JSON, and any file containing the private headers after the download is verified.
If the Mac loses internet access when Charles quits, macOS is still configured to use Charles. Open System Settings → Network → Wi-Fi → Details → Proxies and turn off the HTTP, HTTPS, and automatic proxy entries that point to Charles.
Troubleshooting checklist
Safari says the server cannot be found: the iPhone cannot reach the Mac. Check the Wi-Fi network, Mac IP, port, access-control prompt, firewall, and VPN.
Charles shows only CONNECT tunnels: enable full trust for the Charles certificate and add api.1core.com:443 to SSL Proxying.
The app stops loading after Charles quits: turn the iPhone’s Wi-Fi proxy off.
The Mac stops loading pages after Charles quits: disable the Mac’s Charles proxy settings; the iPhone-only workflow does not need them.
The API works but photo downloads return 403: the signed media URLs expired. Fetch a fresh API page and retry those files.
Modern TLS requests fail: upgrade Charles. Do not spend time debugging a years-old build.
Charles exits during a long session: save the capture early. Once you have one valid request, the phone and Charles are no longer needed for the downloader, provided the captured authorization headers remain valid.