Glowb Dev Docs
SaaS APIAgency API

Agency Branding API

에이전시 로고·파비콘 URL 저장 및 파일 업로드

브랜딩/로고·파비콘

에이전시 로고와 파비콘은 두 단계로 처리합니다. 파일을 업로드해 URL을 받고, 그 URL을 PATCH /agency/me/branding으로 저장합니다.

파비콘 규칙

저장 상태의미로고를 저장하면응답 faviconUrl
미설정한 번도 지정하지 않음로고에서 파비콘을 자동 생성해 저장생성된 URL (생성 실패 시 null)
직접 업로드faviconUrl에 URL을 저장함유지 (덮어쓰지 않음)저장한 URL
자동 생성로고에서 만들어짐로고가 바뀌면 새 로고로 다시 생성생성된 URL
해제faviconUrl에 빈 문자열을 저장함생성하지 않음 (아이콘 없음 유지)null
  • 업로드든 자동 생성이든 이미지는 비율을 유지한 채 투명 정사각 캔버스 가운데에 놓은 180x180 PNG로 변환됩니다.
  • 지원 형식: PNG, JPG, GIF, WEBP, SVG. SVG는 스크립트와 외부 참조(외부 이미지, 외부 CSS, 외부 DTD)를 제거한 뒤 래스터화합니다.
  • AI, ZIP처럼 이미지가 아닌 로고는 자동 생성하지 않습니다(파비콘 없음).
  • 원본은 5MB, 2,500만 픽셀 이하만 받습니다.

PATCH /agency/me/branding은 이미 확보한 로고 URL을 저장하는 API입니다. POST /agency/branding/logo는 multipart 파일을 서버가 받아 S3에 업로드하고 logoUrl을 반환하는 API입니다. presigned URL 전용 구조가 아닙니다.

로고·파비콘 URL 저장

항목값
메서드PATCH
경로/agency/me/branding 또는 /ai/agency/me/branding
인증필요
권한ROLE_AGENCY
PATCH /agency/me/branding HTTP/1.1
Host: api.glowb.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: application/json

{
  "logoUrl": "https://cdn.example.com/agency/logo.png",
  "faviconUrl": "https://d3mp6eqt0w2808.cloudfront.net/business/demo-agency/brand-favicon/1758412800000.png"
}

Request Body

Prop

Type

응답

{
  "logoUrl": "https://cdn.example.com/agency/logo.png",
  "faviconUrl": "https://d3mp6eqt0w2808.cloudfront.net/business/demo-agency/brand-favicon/1758412800000.png"
}

로고에서 파비콘을 자동 생성하다 실패해도(이미지 다운로드·변환·업로드 오류 등) 로고 저장은 성공으로 응답하며, faviconUrl은 null로 비워 둡니다. 예전에는 일부 변환 오류가 로고 저장까지 INTERNAL_SERVER_ERROR로 실패시켰습니다.

로고 파일 업로드

이 API는 에이전시 본인 전용입니다. SecurityConfig가 URL 레벨에서 ROLE_ADMIN도 통과시키지만, 서비스가 호출자 본인의 에이전시를 역산하므로(businessType == AGENCY && agency != null) 본인 에이전시가 없는 어드민은 AUTH_002로 거절됩니다. 어드민은 POST /admin/agency/branding/logo를 사용하세요.

항목값
메서드POST
경로/agency/branding/logo 또는 /ai/agency/branding/logo
인증필요
권한ROLE_AGENCY
Content-Typemultipart/form-data
POST /agency/branding/logo HTTP/1.1
Host: api.glowb.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: multipart/form-data; boundary=----boundary

------boundary
Content-Disposition: form-data; name="file"; filename="logo.webp"
Content-Type: image/webp

{binary}
------boundary--
curl -X POST "https://api.glowb.com/agency/branding/logo" \
  -H "Authorization: Bearer {access_token}" \
  -F "file=@logo.webp"
const formData = new FormData();
formData.append('file', file);

const upload = await fetch('/agency/branding/logo', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${accessToken}`,
  },
  body: formData,
});

const { logoUrl } = await upload.json();

응답

{
  "logoUrl": "https://..."
}

파비콘 파일 업로드

로고 업로드와 같은 권한 규칙을 따릅니다. 업로드한 이미지는 180x180 PNG로 변환되어 S3에 올라가고, 반환된 faviconUrl을 PATCH /agency/me/branding으로 저장해야 적용됩니다. 어드민의 에이전시 지정 화면은 POST /admin/agency/branding/favicon을 사용합니다.

항목값
메서드POST
경로/agency/branding/favicon 또는 /ai/agency/branding/favicon
인증필요
권한ROLE_AGENCY
Content-Typemultipart/form-data
curl -X POST "https://api.glowb.com/agency/branding/favicon" \
  -H "Authorization: Bearer {access_token}" \
  -F "file=@favicon.svg"

응답

{
  "faviconUrl": "https://d3mp6eqt0w2808.cloudfront.net/business/demo-agency/brand-favicon/1758412800000.png"
}

에러 응답

glowb는 CustomException을 HTTP 200으로 감싸 내려보냅니다. 실패 판별은 응답 본문의 status/code로 합니다.

본문 code본문 status설명
FILE_EMPTY400빈 파일
AGENCY_FAVICON_IMAGE_UNSUPPORTED400파비콘으로 변환할 수 없는 파일(이미지가 아니거나 손상·조작됨). 손상 파일 일부가 INTERNAL_SERVER_ERROR로 나가던 것을 이 코드로 통일했습니다
AGENCY_FAVICON_FILE_TOO_LARGE4135MB 초과 (args.maxMb)
AGENCY_FAVICON_RESOLUTION_TOO_LARGE4132,500만 픽셀 초과
AGENCY_FAVICON_CONVERT_FAILED500지원 형식인데 변환 중 서버 오류
FILE_UPLOAD_FAILED500S3 업로드 실패

On this page