+
diff --git a/src/lib/goalsApi.js b/src/lib/goalsApi.js
new file mode 100644
index 0000000..7265aac
--- /dev/null
+++ b/src/lib/goalsApi.js
@@ -0,0 +1,49 @@
+const API_BASE_URL = import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:3001'
+
+function buildHeaders(token) {
+ return {
+ 'Content-Type': 'application/json',
+ Authorization: `Bearer ${token}`,
+ }
+}
+
+async function request(path, { method = 'GET', token, body } = {}) {
+ const response = await fetch(`${API_BASE_URL}${path}`, {
+ method,
+ headers: buildHeaders(token),
+ body: body ? JSON.stringify(body) : undefined,
+ })
+
+ const data = await response.json().catch(() => ({}))
+
+ if (!response.ok) {
+ throw new Error(data.message || '목표 데이터를 처리하지 못했습니다.')
+ }
+
+ return data
+}
+
+export async function fetchGoals(token, { query = '', status = 'active' } = {}) {
+ const searchParams = new URLSearchParams()
+
+ if (query) {
+ searchParams.set('query', query)
+ }
+
+ if (status) {
+ searchParams.set('status', status)
+ }
+
+ const queryString = searchParams.toString()
+ return request(`/api/goals${queryString ? `?${queryString}` : ''}`, {
+ token,
+ })
+}
+
+export async function createGoal(token, payload) {
+ return request('/api/goals', {
+ method: 'POST',
+ token,
+ body: payload,
+ })
+}