immich-app/immich · error · ForbiddenException
Sync endpoints cannot be used with API keys
Error message
Sync endpoints cannot be used with API keys
What it means
The sync endpoints require an authenticated session (created via password login), not a machine-learning/API-key auth. throwSessionRequired raises ForbiddenException when the AuthDto has no session attached, because sync checkpoints/acks are scoped to a session.
Solutions
- Authenticate with username/password login to obtain a session instead of an API key
- Use the Immich mobile app or a session-based client for sync operations
- If scripting is required, log in via POST /api/auth/login and use the returned session token
Example fix
// before
headers: { 'x-api-key': apiKey }
call GET /api/sync/acks
// after
const { accessToken } = await login(email, password)
headers: { Authorization: 'Bearer ' + accessToken }
call GET /api/sync/acks Defensive patterns
Strategy: validation
Validate before calling
const isSyncCapable = (auth) => Boolean(auth.session?.id);
if (!isSyncCapable(auth)) throw new Error('Sync requires a login session, not an API key'); Type guard
function hasSession(auth) { return typeof auth === 'object' && auth !== null && 'session' in auth && auth.session != null && typeof auth.session.id === 'string'; } Try / catch
try {
await syncClient.getAcks();
} catch (e) {
if (e.status === 403) { await loginWithPassword(); /* retry with session */ }
} Prevention
- Use API keys only for non-sync endpoints
- Create sessions via /api/auth/login for sync workloads
- Document that sync APIs are mobile/session-only
When it happens
Trigger: Calling any sync endpoint (getAcks, setAcks, deleteAcks, streamInternal) with an AuthDto whose auth.session is undefined — i.e. authenticated via API key or another non-session auth type.
Common situations: Scripts using an API key to call /api/sync endpoints; mobile-client-only sync API invoked from automation; using API keys generated for external tools.
Related errors
AI-assisted analysis of immich-app/immich@f48d4b3321 (2026-09-15).
Data as JSON: /api/errors/d63c8a88ceabe569.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/sync.service.ts:97
SyncRequestType.AlbumUsersV1,
SyncRequestType.AlbumToAssetsV1,
SyncRequestType.AssetExifsV1,
SyncRequestType.AlbumAssetExifsV1,
SyncRequestType.AssetOcrV1,
SyncRequestType.PartnerAssetExifsV1,
SyncRequestType.MemoriesV1,
SyncRequestType.MemoryToAssetsV1,
SyncRequestType.PeopleV1,
SyncRequestType.AssetFacesV1,
SyncRequestType.AssetFacesV2,
SyncRequestType.AssetFacesV3,
SyncRequestType.UserMetadataV1,
SyncRequestType.AssetMetadataV1,
SyncRequestType.AssetEditsV1,
];
const throwSessionRequired = () => {
throw new ForbiddenException('Sync endpoints cannot be used with API keys');
};
@Injectable()
export class SyncService extends BaseService {
getAcks(auth: AuthDto) {
const sessionId = auth.session?.id;
if (!sessionId) {
return throwSessionRequired();
}
return this.syncCheckpointRepository.getAll(sessionId);
}
async setAcks(auth: AuthDto, dto: SyncAckSetDto) {
const sessionId = auth.session?.id;
if (!sessionId) {
return throwSessionRequired();
}View on GitHub (pinned to f48d4b3321)