title: Retrofit multiple response types
body: <p>How can I use Retrofit2 to parse these two kinds of API responses?</p>
  
  <p>Ok response (HTTP 200):</p>
  
  <pre><code>{
      "data": {
          "foo": "bar"
      }
  }
  </code></pre>
  
  <p>Error response (HTTP 200):</p>
  
  <pre><code>{
      "error": {
          "foo": "bar"
      }
  }
  </code></pre>
  
  <p>I've read tons of SO questions and tutorials, but I don't know how to do that, I've tried:</p>
  
  <pre><code>GsonBuilder gsonBuilder = new GsonBuilder();
  gsonBuilder.registerTypeAdapterFactory(new ItemTypeAdapterFactory());
  Gson gson = gsonBuilder.create();
  
  final Retrofit retrofit = new Retrofit.Builder()
          .client(getOkHttpClient())
          .baseUrl(Constants.API_BASE_URL)
          .addConverterFactory(GsonConverterFactory.create(gson))
          .build();
  </code></pre>
  
  <p>And this is my ItemTypeAdapterFactory:</p>
  
  <pre><code>class ItemTypeAdapterFactory implements TypeAdapterFactory {
  
      public &lt;T&gt; TypeAdapter&lt;T&gt; create(final Gson gson, final TypeToken&lt;T&gt; type) {
  
          final TypeAdapter&lt;T&gt; delegate = gson.getDelegateAdapter(this, type);
          final TypeAdapter&lt;JsonElement&gt; elementAdapter = gson.getAdapter(JsonElement.class);
  
          return new TypeAdapter&lt;T&gt;() {
  
              public void write(JsonWriter out, T value) throws IOException {
                  delegate.write(out, value);
              }
  
              public T read(JsonReader in) throws IOException {
  
                  JsonElement jsonElement = elementAdapter.read(in);
  
                  if (jsonElement.isJsonObject()) {
                      JsonObject jsonObject = jsonElement.getAsJsonObject();
  
                      // Data key
                      if (jsonObject.has(Constants.JSON_KEY_DATA)) {
  
                          JsonElement jsonData = jsonObject.get(Constants.JSON_KEY_DATA);
  
                          // Primitive
                          if (jsonData.isJsonPrimitive()) {
                              jsonElement = jsonData.getAsJsonPrimitive();
                          }
                          // JSON object
                          else if (jsonData.isJsonObject()) {
                              jsonElement = jsonData;
                          }
                          // JSON object array
                          else if (jsonData.isJsonArray()) {
                              jsonElement = jsonData.getAsJsonArray();
                          }
                      }
                  }
  
                  return delegate.fromJsonTree(jsonElement);
              }
          }.nullSafe();
      }
  }
  </code></pre>
  
  <p>But now I don't know the type to be declared on retrofit2 interface, inside Call:</p>
  
  <pre><code>@GET("login")
  Call&lt;?&gt; login(@Query(Constants.API_PARAM_TOKEN) String token);
  </code></pre>
  
  <p>Could you please point me in the right direction? </p>