diff --git a/framework/commercelayer/api/endpoints/login/index.ts b/framework/commercelayer/api/endpoints/login/index.ts
index 491bf0ac9..86aa11793 100644
--- a/framework/commercelayer/api/endpoints/login/index.ts
+++ b/framework/commercelayer/api/endpoints/login/index.ts
@@ -1 +1,18 @@
-export default function noopApi(...args: any[]): void {}
+import { GetAPISchema, createEndpoint } from '@commerce/api'
+import loginEndpoint from '@commerce/api/endpoints/login'
+import type { LoginSchema } from '../../../types/login'
+import type { CommercelayerAPI } from '../..'
+import login from './login'
+
+export type LoginAPI = GetAPISchema<CommercelayerAPI, LoginSchema>
+
+export type LoginEndpoint = LoginAPI['endpoint']
+
+export const handlers: LoginEndpoint['handlers'] = { login }
+
+const loginApi = createEndpoint<LoginAPI>({
+  handler: loginEndpoint,
+  handlers,
+})
+
+export default loginApi
\ No newline at end of file
diff --git a/framework/commercelayer/api/endpoints/login/login.ts b/framework/commercelayer/api/endpoints/login/login.ts
new file mode 100644
index 000000000..61cd12109
--- /dev/null
+++ b/framework/commercelayer/api/endpoints/login/login.ts
@@ -0,0 +1,47 @@
+import { FetcherError } from '@commerce/utils/errors'
+import { getAccessToken } from '../../index'
+import type { LoginEndpoint } from '.'
+
+const login: LoginEndpoint['handlers']['login'] = async ({
+  res,
+  body: { email, password },
+  config,
+  commerce,
+}) => {
+  if (!(email && password)) {
+    return res.status(400).json({
+      data: null,
+      errors: [{ message: 'Invalid request' }],
+    })
+  }
+
+  try {
+    const user = { email, password };
+    const getToken = await getAccessToken(user);
+    await config.apiFetch(`/api/customers/${getToken.customerId}`, {
+      method: 'GET'
+    })
+  } catch (error) {
+    if (error instanceof FetcherError &&
+      /invalid credentials/i.test(error.message)) {
+        return res.status(401).json({
+          data: null,
+          errors: [
+            {
+              message:
+                'Cannot find an account that matches the provided credentials',
+              code: 'INVALID_CREDENTIALS',
+            },
+          ],
+        })
+      }
+
+    throw error
+  }
+
+  await commerce.login({ variables: { email, password }, config, res })
+
+  res.status(200).json({ data: null })
+}
+
+export default login
\ No newline at end of file
diff --git a/framework/commercelayer/api/endpoints/signup/index.ts b/framework/commercelayer/api/endpoints/signup/index.ts
index 491bf0ac9..3d43b121e 100644
--- a/framework/commercelayer/api/endpoints/signup/index.ts
+++ b/framework/commercelayer/api/endpoints/signup/index.ts
@@ -1 +1,18 @@
-export default function noopApi(...args: any[]): void {}
+import { GetAPISchema, createEndpoint } from '@commerce/api'
+import signupEndpoint from '@commerce/api/endpoints/signup'
+import type { SignupSchema } from '../../../types/signup'
+import type { CommercelayerAPI } from '../..'
+import signup from './signup'
+
+export type SignupAPI = GetAPISchema<CommercelayerAPI, SignupSchema>
+
+export type SignupEndpoint = SignupAPI['endpoint']
+
+export const handlers: SignupEndpoint['handlers'] = { signup }
+
+const singupApi = createEndpoint<SignupAPI>({
+  handler: signupEndpoint,
+  handlers,
+})
+
+export default singupApi
diff --git a/framework/commercelayer/api/endpoints/signup/signup.ts b/framework/commercelayer/api/endpoints/signup/signup.ts
new file mode 100644
index 000000000..204379a30
--- /dev/null
+++ b/framework/commercelayer/api/endpoints/signup/signup.ts
@@ -0,0 +1,55 @@
+import { CommercelayerApiError } from '../../utils/errors'
+import type { SignupEndpoint } from '.'
+
+const signup: SignupEndpoint['handlers']['signup'] = async ({
+  res,
+  body: { email, password },
+  config,
+  commerce,
+}) => {
+  if (!(email && password)) {
+    return res.status(400).json({
+      data: null,
+      errors: [{ message: 'Invalid request' }],
+    })
+  }
+
+  try {
+    await config.apiFetch('/api/customers', {
+      method: 'POST',
+      body: {
+          data: {
+            type: 'customers',
+            attributes: {
+              email: email,
+              password: password,
+            },
+          },
+        },
+    })
+  } catch (error) {
+    if (error instanceof CommercelayerApiError && error.status === 422) {
+      const inputEmail = error.data?.errors.meta.value
+
+      if ('code' in error.data?.errors) {
+        return res.status(400).json({
+          data: null,
+          errors: [
+            {
+              message: `A user already exists with ${inputEmail}`,
+              code: 'USER_EXISTS',
+            },
+          ],
+        })
+      }
+    }
+
+    throw error
+  }
+
+  await commerce.login({ variables: { email, password }, res, config })
+
+  res.status(200).json({ data: null })
+}
+
+export default signup
diff --git a/framework/commercelayer/api/index.ts b/framework/commercelayer/api/index.ts
index 8b7a47d76..2af8db558 100644
--- a/framework/commercelayer/api/index.ts
+++ b/framework/commercelayer/api/index.ts
@@ -12,7 +12,6 @@ import getAllProducts from './operations/get-all-products'
 import getProduct from './operations/get-product'
 
 import { getToken } from './utils/get-token'
-import fetch from './utils/fetch'
 
 export interface CommercelayerConfig extends Omit<CommerceAPIConfig, 'fetch'> {
   apiClientId: string
@@ -36,19 +35,19 @@ const MARKET_SCOPE = process.env.COMMERCELAYER_MARKET_SCOPE
 
 if (!CLIENT_ID) {
   throw new Error(
-    `The environment variable COMMERCELAYER_CLIENT_ID is missing and it's required to access your store`
+    `The environment variable COMMERCELAYER_CLIENT_ID is missing and it's required.`
   )
 }
 
 if (!ENDPOINT) {
   throw new Error(
-    `The environment variable COMMERCELAYER_ENDPOINT is missing and it's required to access your store`
+    `The environment variable COMMERCELAYER_ENDPOINT is missing and it's required.`
   )
 }
 
 if (!MARKET_SCOPE) {
   throw new Error(
-    `The environment variable COMMERCELAYER_MARKET_SCOPE is missing and it's required to access your store`
+    `The environment variable COMMERCELAYER_MARKET_SCOPE is missing and it's required.`
   )
 }
 
diff --git a/framework/commercelayer/api/utils/errors.ts b/framework/commercelayer/api/utils/errors.ts
new file mode 100644
index 000000000..6acc9fd0d
--- /dev/null
+++ b/framework/commercelayer/api/utils/errors.ts
@@ -0,0 +1,22 @@
+import type { Response } from '@vercel/fetch'
+
+export class CommercelayerApiError extends Error {
+  status: number
+  res: Response
+  data: any
+
+  constructor(msg: string, res: Response, data?: any) {
+    super(msg)
+    this.name = 'CommercelayerApiError'
+    this.status = res.status
+    this.res = res
+    this.data = data
+  }
+}
+
+export class CommercelayerNetworkError extends Error {
+  constructor(msg: string) {
+    super(msg)
+    this.name = 'CommercelayerNetworkError'
+  }
+}
\ No newline at end of file
diff --git a/framework/commercelayer/api/utils/fetch-api.ts b/framework/commercelayer/api/utils/fetch-api.ts
index 85ca08c1b..6764feaf5 100644
--- a/framework/commercelayer/api/utils/fetch-api.ts
+++ b/framework/commercelayer/api/utils/fetch-api.ts
@@ -16,21 +16,20 @@ const fetchApi =
     const token = getToken?.accessToken
     const res = await fetch(config.commerceUrl + endpoint, {
       ...fetchOptions,
-      method: 'POST',
       headers: {
         ...fetchOptions?.headers,
         'Content-Type': 'application/json',
         Authorization: `Bearer ${token}`,
       },
-      body: JSON.stringify({
+      body: JSON.stringify([
         query,
-      }),
+      ]),
     })
 
     const json = await res.json()
     if (json.errors) {
       throw new FetcherError({
-        errors: json.errors ?? [{ message: 'Failed to fetch for API' }],
+        errors: json.errors ?? [{ message: 'Failed to fetch Commerce Layer API' }],
         status: res.status,
       })
     }
diff --git a/framework/commercelayer/auth/use-login.tsx b/framework/commercelayer/auth/use-login.tsx
index 28351dc7f..aa74689b9 100644
--- a/framework/commercelayer/auth/use-login.tsx
+++ b/framework/commercelayer/auth/use-login.tsx
@@ -1,16 +1,40 @@
-import { MutationHook } from '@commerce/utils/types'
+import { useCallback } from 'react'
+import type { MutationHook } from '@commerce/utils/types'
+import { CommerceError } from '@commerce/utils/errors'
 import useLogin, { UseLogin } from '@commerce/auth/use-login'
+import type { LoginHook } from '../types/login'
+import useCustomer from '../customer/use-customer'
 
 export default useLogin as UseLogin<typeof handler>
 
-export const handler: MutationHook<any> = {
+export const handler: MutationHook<LoginHook> = {
   fetchOptions: {
-    query: '',
+    url: '/api/customers',
+    method: 'GET',
   },
-  async fetcher() {
-    return null
+  async fetcher({ input: { email, password }, options, fetch }) {
+    if (!(email && password)) {
+      throw new CommerceError({
+        message:
+          'An email address and password are required to login',
+      })
+    }
+
+    return fetch({
+      ...options,
+      body: { email, password },
+    })
   },
-  useHook: () => () => {
-    return async function () {}
+  useHook: ({ fetch }) => () => {
+    const { revalidate } = useCustomer()
+
+    return useCallback(
+      async function login(input) {
+        const data = await fetch({ input })
+        await revalidate()
+        return data
+      },
+      [fetch, revalidate]
+    )
   },
-}
+}
\ No newline at end of file
diff --git a/framework/commercelayer/auth/use-signup.tsx b/framework/commercelayer/auth/use-signup.tsx
index e9ad13458..d1cfbbe9a 100644
--- a/framework/commercelayer/auth/use-signup.tsx
+++ b/framework/commercelayer/auth/use-signup.tsx
@@ -1,19 +1,44 @@
 import { useCallback } from 'react'
-import useCustomer from '../customer/use-customer'
-import { MutationHook } from '@commerce/utils/types'
+import type { MutationHook } from '@commerce/utils/types'
+import { CommerceError } from '@commerce/utils/errors'
 import useSignup, { UseSignup } from '@commerce/auth/use-signup'
+import type { SignupHook } from '../types/signup'
+import useCustomer from '../customer/use-customer'
 
 export default useSignup as UseSignup<typeof handler>
 
-export const handler: MutationHook<any> = {
+export const handler: MutationHook<SignupHook> = {
   fetchOptions: {
-    query: '',
+    url: '/api/customers',
+    method: 'POST',
   },
-  async fetcher() {
-    return null
+  async fetcher({
+    input: { email, password },
+    options,
+    fetch,
+  }) {
+    if (!(email && password)) {
+      throw new CommerceError({
+        message:
+          'An email address and password are required to signup',
+      })
+    }
+
+    return fetch({
+      ...options,
+      body: { email, password },
+    })
   },
-  useHook:
-    ({ fetch }) =>
-    () =>
-    () => {},
-}
+  useHook: ({ fetch }) => () => {
+    const { revalidate } = useCustomer()
+
+    return useCallback(
+      async function signup(input) {
+        const data = await fetch({ input })
+        await revalidate()
+        return data
+      },
+      [fetch, revalidate]
+    )
+  },
+}
\ No newline at end of file
diff --git a/framework/commercelayer/commerce.config.json b/framework/commercelayer/commerce.config.json
index 261211527..460e52b3a 100644
--- a/framework/commercelayer/commerce.config.json
+++ b/framework/commercelayer/commerce.config.json
@@ -1,9 +1,9 @@
 {
-  "provider": "local",
+  "provider": "commercelayer",
   "features": {
     "wishlist": false,
     "cart": false,
     "search": false,
-    "customerAuth": false
+    "customerAuth": true
   }
 }
diff --git a/framework/commercelayer/index.tsx b/framework/commercelayer/index.tsx
index 2ec304f63..9c614577f 100644
--- a/framework/commercelayer/index.tsx
+++ b/framework/commercelayer/index.tsx
@@ -1,13 +1,13 @@
 import * as React from 'react'
 import { ReactNode } from 'react'
-import { localProvider } from './provider'
+import { commerceLayerProvider } from './provider'
 import {
   CommerceConfig,
   CommerceProvider as CoreCommerceProvider,
   useCommerce as useCoreCommerce,
 } from '@commerce'
 
-export const localConfig: CommerceConfig = {
+export const commerceLayerConfig: CommerceConfig = {
   locale: 'en-us',
   cartCookie: 'session',
 }
@@ -21,8 +21,8 @@ export function CommerceProvider({
 } & Partial<CommerceConfig>) {
   return (
     <CoreCommerceProvider
-      provider={localProvider}
-      config={{ ...localConfig, ...config }}
+      provider={commerceLayerProvider}
+      config={{ ...commerceLayerConfig, ...config }}
     >
       {children}
     </CoreCommerceProvider>
diff --git a/framework/commercelayer/provider.ts b/framework/commercelayer/provider.ts
index e6a2b0a21..f5e9e55c4 100644
--- a/framework/commercelayer/provider.ts
+++ b/framework/commercelayer/provider.ts
@@ -9,8 +9,8 @@ import { handler as useLogin } from './auth/use-login'
 import { handler as useLogout } from './auth/use-logout'
 import { handler as useSignup } from './auth/use-signup'
 
-export type Provider = typeof localProvider
-export const localProvider = {
+export type Provider = typeof commerceLayerProvider
+export const commerceLayerProvider = {
   locale: 'en-us',
   cartCookie: 'session',
   fetcher: fetcher,
diff --git a/framework/commercelayer/types/cart.ts b/framework/commercelayer/types/cart.ts
new file mode 100644
index 000000000..6ed5c6c64
--- /dev/null
+++ b/framework/commercelayer/types/cart.ts
@@ -0,0 +1 @@
+export * from '@commerce/types/cart'
diff --git a/framework/commercelayer/types/checkout.ts b/framework/commercelayer/types/checkout.ts
new file mode 100644
index 000000000..4e2412ef6
--- /dev/null
+++ b/framework/commercelayer/types/checkout.ts
@@ -0,0 +1 @@
+export * from '@commerce/types/checkout'
diff --git a/framework/commercelayer/types/common.ts b/framework/commercelayer/types/common.ts
new file mode 100644
index 000000000..b52c33a4d
--- /dev/null
+++ b/framework/commercelayer/types/common.ts
@@ -0,0 +1 @@
+export * from '@commerce/types/common'
diff --git a/framework/commercelayer/types/customer.ts b/framework/commercelayer/types/customer.ts
new file mode 100644
index 000000000..87c9afcc4
--- /dev/null
+++ b/framework/commercelayer/types/customer.ts
@@ -0,0 +1 @@
+export * from '@commerce/types/customer'
diff --git a/framework/commercelayer/types/index.ts b/framework/commercelayer/types/index.ts
new file mode 100644
index 000000000..7ab0b7f64
--- /dev/null
+++ b/framework/commercelayer/types/index.ts
@@ -0,0 +1,25 @@
+import * as Cart from './cart'
+import * as Checkout from './checkout'
+import * as Common from './common'
+import * as Customer from './customer'
+import * as Login from './login'
+import * as Logout from './logout'
+import * as Page from './page'
+import * as Product from './product'
+import * as Signup from './signup'
+import * as Site from './site'
+import * as Wishlist from './wishlist'
+
+export type {
+  Cart,
+  Checkout,
+  Common,
+  Customer,
+  Login,
+  Logout,
+  Page,
+  Product,
+  Signup,
+  Site,
+  Wishlist,
+}
diff --git a/framework/commercelayer/types/login.ts b/framework/commercelayer/types/login.ts
new file mode 100644
index 000000000..ab11a420a
--- /dev/null
+++ b/framework/commercelayer/types/login.ts
@@ -0,0 +1,11 @@
+import * as Core from '@commerce/types/login'
+import { LoginBody, LoginTypes } from '@commerce/types/login'
+
+export * from '@commerce/types/login'
+
+export type LoginHook<T extends LoginTypes = LoginTypes> = {
+  data: null
+  actionInput: LoginBody
+  fetcherInput: LoginBody
+  body: T['body']
+}
diff --git a/framework/commercelayer/types/logout.ts b/framework/commercelayer/types/logout.ts
new file mode 100644
index 000000000..9f0a466af
--- /dev/null
+++ b/framework/commercelayer/types/logout.ts
@@ -0,0 +1 @@
+export * from '@commerce/types/logout'
diff --git a/framework/commercelayer/types/page.ts b/framework/commercelayer/types/page.ts
new file mode 100644
index 000000000..20ec8ea38
--- /dev/null
+++ b/framework/commercelayer/types/page.ts
@@ -0,0 +1 @@
+export * from '@commerce/types/page'
diff --git a/framework/commercelayer/types/product.ts b/framework/commercelayer/types/product.ts
new file mode 100644
index 000000000..c776d58fa
--- /dev/null
+++ b/framework/commercelayer/types/product.ts
@@ -0,0 +1 @@
+export * from '@commerce/types/product'
diff --git a/framework/commercelayer/types/signup.ts b/framework/commercelayer/types/signup.ts
new file mode 100644
index 000000000..58543c6f6
--- /dev/null
+++ b/framework/commercelayer/types/signup.ts
@@ -0,0 +1 @@
+export * from '@commerce/types/signup'
diff --git a/framework/commercelayer/types/site.ts b/framework/commercelayer/types/site.ts
new file mode 100644
index 000000000..bfef69cf9
--- /dev/null
+++ b/framework/commercelayer/types/site.ts
@@ -0,0 +1 @@
+export * from '@commerce/types/site'
diff --git a/framework/commercelayer/types/wishlist.ts b/framework/commercelayer/types/wishlist.ts
new file mode 100644
index 000000000..8907fbf82
--- /dev/null
+++ b/framework/commercelayer/types/wishlist.ts
@@ -0,0 +1 @@
+export * from '@commerce/types/wishlist'
diff --git a/tsconfig.json b/tsconfig.json
index db71b765b..51c174bd6 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -24,8 +24,8 @@
       "@components/*": ["components/*"],
       "@commerce": ["framework/commerce"],
       "@commerce/*": ["framework/commerce/*"],
-      "@framework": ["framework/local"],
-      "@framework/*": ["framework/local/*"]
+      "@framework": ["framework/commercelayer"],
+      "@framework/*": ["framework/commercelayer/*"]
     }
   },
   "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"],