# API: Please accept data in the body as JSON

**URL:** <https://forum.beeminder.com/t/api-please-accept-data-in-the-body-as-json/10843>\
**Category:** Bugabee\
**Created:** [February 26, 2023, 3:43pm UTC](https://forum.beeminder.com/t/api-please-accept-data-in-the-body-as-json/10843 "2023-02-26T15:43:32Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![narthur](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/narthur/32/5113_2.png) [@narthur](https://forum.beeminder.com/u/narthur)\
**Post date:** [February 26, 2023, 3:43pm UTC](https://forum.beeminder.com/t/api-please-accept-data-in-the-body-as-json/10843/1 "2023-02-26T15:43:32Z")

</div>

Currently it appears that the API does not accept data in the form of a JSON-stringified body. So, for example, in Node the following code does not work:

```typescript
async function api({
  route,
  method = "get",
  data,
}: {
  route: string;
  method?: "get" | "post" | "put" | "delete";
  data?: Record<string, unknown>;
}) {
  const result = await fetch(`${API_ROOT}${route}?auth_token=${API_KEY}`, {
    method,
    body: JSON.stringify(data),
  });

  if (!result.ok) {
    throw new Error(`${result.status} ${result.statusText}`);
  }

  return result.json();
}

```

Whereas this code does work:

```typescript
async function api({
  route,
  method = "get",
  data,
}: {
  route: string;
  method?: "get" | "post" | "put" | "delete";
  data?: Record<string, unknown>;
}) {
  const form = new URLSearchParams();
  if (data) {
    Object.entries(data).forEach(([key, value]) => {
      form.append(key, value as string);
    });
  }

  const result = await fetch(`${API_ROOT}${route}?auth_token=${API_KEY}`, {
    method,
    body: data && form,
  });

  if (!result.ok) {
    throw new Error(`${result.status} ${result.statusText}`);
  }

  return result.json();
}

```

I would prefer to use the former code since it’s easier both to read and to write, and requires less code. Could the API be modified to accept both URL-encoded form data (the second example) and JSON bodies (the first example)?

---

<div class="post-metadata">

**Author:** ![zzq](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/zzq/32/6471_2.png) [@zzq](https://forum.beeminder.com/u/zzq)\
**Post date:** [February 26, 2023, 6:22pm UTC](https://forum.beeminder.com/t/api-please-accept-data-in-the-body-as-json/10843/2 "2023-02-26T18:22:50Z")

</div>

As is standard, you need to pass a `Content-Type` header to specify the format of the data that you’re passing (for JSON, that’s `application/json`), at least if it isn’t the default (Beeminder by default assumes form encoding, `application/x-www-form-urlencoded`.)

In your example with `fetch`, that would look something like

```javascript
const result = await fetch(`${API_ROOT}${route}?auth_token=${API_KEY}`, {
  method,
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(data)
})

```

---

<div class="post-metadata">

**Author:** ![narthur](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/narthur/32/5113_2.png) [@narthur](https://forum.beeminder.com/u/narthur)\
**Post date:** [February 26, 2023, 6:25pm UTC](https://forum.beeminder.com/t/api-please-accept-data-in-the-body-as-json/10843/3 "2023-02-26T18:25:19Z")

</div>

Oh, gotcha! I’ll try that and see if it works. Makes since that it may have been user error here. 😅

---

<div class="post-metadata">

**Author:** ![narthur](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/narthur/32/5113_2.png) [@narthur](https://forum.beeminder.com/u/narthur)\
**Post date:** [February 26, 2023, 9:25pm UTC](https://forum.beeminder.com/t/api-please-accept-data-in-the-body-as-json/10843/4 "2023-02-26T21:25:57Z")

</div>

Yup, that was it! Appreciate your help, @zzq 😄
