diff --git a/src/app/(with-header)/myactivity/utils/uploadImage.ts b/src/app/(with-header)/myactivity/utils/uploadImage.ts
new file mode 100644
index 0000000..dc4d69e
--- /dev/null
+++ b/src/app/(with-header)/myactivity/utils/uploadImage.ts
@@ -0,0 +1,14 @@
+import { privateInstance } from '@/apis/privateInstance';
+
+export async function uploadImage(file: File): Promise {
+ const formData = new FormData();
+ formData.append('image', file);
+
+ const res = await privateInstance.post(`/image`, formData, {
+ headers: {
+ 'Content-Type': 'multipart/form-data',
+ },
+ });
+
+ return res.data.replace(/^"+|"+$/g, '');
+}
diff --git a/src/app/api/addActivity/route.ts b/src/app/api/addActivity/route.ts
new file mode 100644
index 0000000..a193cc5
--- /dev/null
+++ b/src/app/api/addActivity/route.ts
@@ -0,0 +1,69 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { cookies } from 'next/headers';
+import axios, { AxiosError } from 'axios';
+
+const BACKEND_BASE_URL = process.env.NEXT_PUBLIC_API_SERVER_URL;
+
+interface ErrorResponse {
+ message?: string;
+ error?: string;
+}
+
+export async function POST(req: NextRequest) {
+ const cookieStore = await cookies();
+ const accessToken = cookieStore.get('accessToken')?.value;
+
+ if (!accessToken) {
+ return NextResponse.json({ message: '액세스 토큰 없음' }, { status: 401 });
+ }
+
+ try {
+ const body = await req.json();
+ const {
+ title,
+ category,
+ description,
+ address,
+ price,
+ schedules,
+ bannerImageUrl,
+ subImageUrls,
+ } = body;
+
+ const response = await axios.post(
+ `${BACKEND_BASE_URL}/activities`,
+ {
+ title,
+ category,
+ description,
+ address,
+ price,
+ schedules,
+ bannerImageUrl,
+ subImageUrls,
+ },
+ {
+ headers: {
+ 'Content-Type': 'application/json',
+ Authorization: `Bearer ${accessToken}`,
+ },
+ },
+ );
+
+ return NextResponse.json(response.data, { status: 201 });
+ } catch (error: unknown) {
+ console.error('체험 등록 에러:', error);
+
+ if (axios.isAxiosError(error)) {
+ const axiosError = error as AxiosError;
+ const status = axiosError.response?.status || 500;
+ const detail = axiosError.response?.data;
+
+ const errorMessage = detail?.message || detail?.error || '체험 등록 실패';
+
+ return NextResponse.json({ message: errorMessage }, { status });
+ }
+
+ return NextResponse.json({ message: '서버 내부 오류' }, { status: 500 });
+ }
+}
diff --git a/src/app/api/image/route.ts b/src/app/api/image/route.ts
new file mode 100644
index 0000000..0a8c2a2
--- /dev/null
+++ b/src/app/api/image/route.ts
@@ -0,0 +1,65 @@
+import { cookies } from 'next/headers';
+import { NextRequest, NextResponse } from 'next/server';
+
+export const config = {
+ api: {
+ bodyParser: false,
+ },
+};
+
+const BACKEND_BASE_URL = process.env.NEXT_PUBLIC_API_SERVER_URL;
+
+export async function POST(req: NextRequest) {
+ const cookieStore = await cookies();
+ const accessToken = cookieStore.get('accessToken')?.value;
+
+ if (!accessToken) {
+ return NextResponse.json({ message: '액세스 토큰 없음' }, { status: 401 });
+ }
+
+ try {
+ const formData = await req.formData();
+ const file = formData.get('image');
+
+ if (!(file instanceof File)) {
+ return NextResponse.json(
+ { message: '이미지 파일 없음' },
+ { status: 400 },
+ );
+ }
+
+ const uploadForm = new FormData();
+ uploadForm.append('image', file);
+
+ const backendRes = await fetch(`${BACKEND_BASE_URL}/activities/image`, {
+ method: 'POST',
+ body: uploadForm,
+ headers: {
+ Authorization: `Bearer ${accessToken}`,
+ },
+ });
+
+ if (!backendRes.ok) {
+ return NextResponse.json(
+ { message: '백엔드 이미지 업로드 실패' },
+ { status: backendRes.status },
+ );
+ }
+
+ const result = await backendRes.json();
+
+ if (!result.activityImageUrl) {
+ return NextResponse.json(
+ { message: '이미지 URL이 백엔드 응답에 없습니다.' },
+ { status: 500 },
+ );
+ }
+
+ const Image = JSON.stringify(result.activityImageUrl);
+
+ return NextResponse.json(Image, { status: 200 });
+ } catch (error) {
+ console.error('업로드 중 에러:', error);
+ return NextResponse.json({ message: '서버 내부 오류' }, { status: 500 });
+ }
+}