src/main/java/com/tenor/android/core/measurable/MeasurableViewHolderEvent.java
public class MeasurableViewHolderEvent implements Serializable {

    private static final long serialVersionUID = 2288577105348192434L;

    @SerializedName("source_id")
    private final String mSourceId;

    @SerializedName("timestamp")
    private final String mTimestamp;

    @SerializedName("action")
    private final String mAction;

    @SerializedName("timezone")
    private final String mUtcOffset;

    @ItemVisualPosition.Value
    @SerializedName("visual_pos")
    private final String mVisualPosition;

    @SerializedName("elapsed_ms")
    private String mDuration;

    @SerializedName("visible_fraction")
    private String mVisibleFraction;

    public MeasurableViewHolderEvent(@NonNull MeasurableViewHolderData data,
                                     @NonNull String utcOffset) {
        this(data.getId(), ViewAction.VIEW, utcOffset, data.getVisualPosition());
        mDuration = String.format(Locale.US, "%d", data.getAccumulatedVisibleDuration());
        mVisibleFraction = String.format(Locale.US, "%f", data.getVisibleFraction());
    }

    public MeasurableViewHolderEvent(@NonNull String sourceId,
                                     @ViewAction.Value String action,
                                     @NonNull String utcOffset,
                                     @ItemVisualPosition.Value String visualPosition) {
        mSourceId = sourceId;
        mTimestamp = String.format(Locale.US, "%d", System.currentTimeMillis());
        mAction = action;
        mUtcOffset = utcOffset;
        mVisualPosition = visualPosition;
    }
}
src/main/java/com/tenor/android/core/response/impl/PackResponse.java
public class PackResponse extends GifsResponse {

    private static final long serialVersionUID = -6425188470381821462L;

    private String id;
    private String name;

    @NonNull
    public String getId() {
        return StringConstant.getOrEmpty(id);
    }

    @NonNull
    public String getName() {
        return StringConstant.getOrEmpty(name);
    }
}
src/main/java/com/tenor/android/core/response/impl/TrendingGifResponse.java
public class TrendingGifResponse extends GifsResponse {
    private static final long serialVersionUID = -4532798057539811043L;
}
src/main/java/com/tenor/android/core/response/impl/TagsResponse.java
public class TagsResponse extends AbstractResponse {

    private static final long serialVersionUID = -8215681889738059793L;
    private List<Tag> tags;

    @NonNull
    public List<Tag> getTags() {
        return !AbstractListUtils.isEmpty(tags) ? tags : Collections.<Tag>emptyList();
    }
}
src/main/java/com/tenor/android/core/response/impl/AnonIdResponse.java
public class AnonIdResponse extends AbstractResponse {

    private static final long serialVersionUID = -1814022099833831972L;
    @SerializedName(value = "anonid", alternate = {"anon_id"})
    private String id;
    @SerializedName("localid")
    private int localId;

    @NonNull
    public String getId() {
        return StringConstant.getOrEmpty(id);
    }

    public int getLocalId() {
        return localId;
    }
}
src/main/java/com/tenor/android/core/response/impl/EmojiResponse.java
public class EmojiResponse extends AbstractResponse {
    private static final long serialVersionUID = 5979803531976871364L;
    private List<EmojiTag> tags;

    @NonNull
    public List<EmojiTag> getTags() {
        return !AbstractListUtils.isEmpty(tags) ? tags : Collections.<EmojiTag>emptyList();
    }
}
src/main/java/com/tenor/android/core/model/impl/Result.java
public class Result implements IGif {
    private static final long serialVersionUID = -4037633614634142811L;

    private String url;

    @SerializedName("media")
    private List<MediaCollection> medias;

    private double created;
    private int shares;
    private String itemurl;
    private Media composite;

    @SerializedName("hasaudio")
    private boolean hasAudio;

    private String title;
    private String id;
    private List<String> tags;

    @SerializedName("bg_color")
    private String placeholderColor;

    @SerializedName("aspect_ratio")
    private String aspectRatio;

    @SerializedName("feature_info")
    private FeaturedInfo featuredInfo;

    @SerializedName("badge_info")
    private BadgeInfo badgeInfo;

    @SerializedName("source_id")
    private String sourceId;

    /**
     * @return true if asset has sound
     */
    public boolean isHasAudio() {
        return hasAudio;
    }

    @Nullable
    public Media getComposite() {
        return composite;
    }

    /**
     * @return created at timestamp
     */
    public double getCreated() {
        return created;
    }

    /**
     * @return unique result id
     */
    @NonNull
    public String getId() {
        return StringConstant.getOrEmpty(id);
    }

    @Override
    @NonNull
    public String getName() {
        return StringConstant.getOrEmpty(title);
    }

    /**
     * @return collection of {@link Media} formats of this {@link Result}
     */
    @NonNull
    public List<MediaCollection> getMedias() {
        return !AbstractListUtils.isEmpty(medias) ? medias : Collections.<MediaCollection>emptyList();
    }

    /**
     * @return collection of related {@link Tag}s of this {@link Result}
     */
    @NonNull
    public List<String> getTags() {
        return !AbstractListUtils.isEmpty(tags) ? tags : Collections.<String>emptyList();
    }

    /**
     * @return share count of this {@link Result}
     */
    public int getShares() {
        return shares;
    }

    /**
     * @return name of this {@link Result}
     */
    public String getTitle() {
        return title;
    }

    /**
     * @return web url of this {@link Result}
     */
    public String getUrl() {
        return url;
    }

    /**
     * @return alternative web url of this {@link Result}
     */
    public String getItemUrl() {
        return itemurl;
    }

    /**
     * @return placeholder color hex of this {@link Result}
     */
    @NonNull
    public String getPlaceholderColorHex() {
        return ColorHex.parse(placeholderColor, "#000000");
    }

    /**
     * @return aspect ratio of this {@link Result} or the default 1080p aspect ratio, 1.7778f
     */
    @FloatRange(from = 0.01f, to = 5.01f)
    public float getAspectRatio() {
        float ratio = FloatString.parse(aspectRatio, 1.7778f);
        return ratio >= 0.01f && ratio <= 5.01f ? ratio : 1.7778f;
    }

    @Nullable
    public FeaturedInfo getFeaturedInfo() {
        return featuredInfo;
    }

    public boolean hasFeaturedInfo() {
        return featuredInfo != null;
    }

    @Nullable
    public BadgeInfo getBadgeInfo() {
        return badgeInfo;
    }

    public boolean hasBadgeInfo() {
        return badgeInfo != null;
    }

    @NonNull
    public String getSourceId() {
        return StringConstant.getOrEmpty(sourceId);
    }

    public boolean hasSourceId() {
        return !TextUtils.isEmpty(sourceId);
    }
}
src/main/java/com/tenor/android/core/constant/MediaFilter.java
public class MediaFilter {

    @Retention(RetentionPolicy.CLASS)
    @StringDef({MINIMAL, BASIC})
    public @interface Value {
    }

    public static final String MINIMAL = "minimal";
    public static final String BASIC = "basic";
}
src/main/java/com/tenor/android/core/constant/AspectRatioRange.java
public class AspectRatioRange {

    public static final String ALL = "all";
    public static final String STANDARD = "standard";
    public static final String WIDE = "wide";
}
src/main/java/com/tenor/android/core/model/impl/Suggestions.java
public class Suggestions implements Serializable {
    private static final long serialVersionUID = 5805025178874996139L;

    @SerializedName("results")
    private List<String> suggestions;

    @NonNull
    public List<String> getSuggestions() {
        return !AbstractListUtils.isEmpty(suggestions) ? suggestions : Collections.<String>emptyList();
    }
}
src/main/java/com/tenor/android/core/response/impl/SearchSuggestionResponse.java
public class SearchSuggestionResponse extends AbstractResponse {

    private static final long serialVersionUID = 8046525237691607393L;
    private List<String> results;

    @NonNull
    public List<String> getResults() {
        return !AbstractListUtils.isEmpty(results) ? results : Collections.<String>emptyList();
    }
}
src/main/java/com/tenor/android/core/response/impl/GifsResponse.java
public class GifsResponse extends AbstractResponse {
    private static final long serialVersionUID = 2805215887381282883L;
    private String next;
    private List<Result> results;

    public boolean hasNext() {
        return !TextUtils.isEmpty(next);
    }

    @NonNull
    public String getNext() {
        return StringConstant.getOrEmpty(next);
    }

    @NonNull
    public List<Result> getResults() {
        return !AbstractListUtils.isEmpty(results) ? results : Collections.<Result>emptyList();
    }
}
src/main/java/com/tenor/android/core/response/impl/TrendingTermResponse.java
public class TrendingTermResponse extends AbstractResponse {

    private static final long serialVersionUID = -8215681889738059793L;
    private List<String> results;

    @NonNull
    public List<String> getTrendingTerms() {
        return !AbstractListUtils.isEmpty(results) ? results : Collections.<String>emptyList();
    }
}


Question: package com.tenor.android.core.network;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import com.tenor.android.core.constant.AspectRatioRange;
import com.tenor.android.core.constant.MediaFilter;
import com.tenor.android.core.measurable.MeasurableViewHolderEvent;
import com.tenor.android.core.model.impl.Result;
import com.tenor.android.core.model.impl.Suggestions;
import com.tenor.android.core.response.impl.AnonIdResponse;
import com.tenor.android.core.response.impl.EmojiResponse;
import com.tenor.android.core.response.impl.GifsResponse;
import com.tenor.android.core.response.impl.PackResponse;
import com.tenor.android.core.response.impl.SearchSuggestionResponse;
import com.tenor.android.core.response.impl.TagsResponse;
import com.tenor.android.core.response.impl.TrendingGifResponse;
import com.tenor.android.core.response.impl.TrendingTermResponse;
import java.util.Map;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.HEAD;
import retrofit2.http.POST;
import retrofit2.http.Query;
import retrofit2.http.QueryMap;
import retrofit2.http.Url;






/**
 * The network calls
 */
public interface IApiClient {
    /**
     * Search for gifs based on a query tag
     *
     * @param serviceIds       a {@link Map} of a collection of ids for better content delivery experience
     * @param query            <b>term</b> being searched for
     * @param limit            <b>bucket</b> size of each response
     * @param pos              <b>index</b> for where the first result should come from.  If <b>empty</b>, start at the first result
     * @param mediaFilter      one of the options from {@link MediaFilter}
     * @param aspectRatioRange one of the options from {@link AspectRatioRange}
     * @return {@link Call}<{@link GifsResponse}>
     */
    @GET("search")
    @NonNull
    Call<GifsResponse> search(@QueryMap Map<String, String> serviceIds,
                              @Query("q") @NonNull String query,
                              @Query("limit") int limit,
                              @Query("pos") @NonNull String pos,
                              @Query("media_filter") @MediaFilter.Value String mediaFilter,
                              @Query("ar_range") String aspectRatioRange);

    /**
     * Retrieves a set of tags to be displayed as gif categories,
     * which when clicked will perform a gif search of that tag
     *
     * @param serviceIds a {@link Map} of a collection of ids for better content delivery experience
     * @param type       what <b>subset of tags</b> you wish to retrieve
     * @param utcOffset  the timezone
     * @return {@link Call}<{@link TagsResponse}>
     */
    @GET("tags")
    Call<TagsResponse> getTags(@QueryMap Map<String, String> serviceIds, @Query("type") String type,
                               @Query("timezone") String utcOffset);

    /**
     * Retrieves a set of emojis to use in gif searching.
     * Clicking on these emojis can perform searches with the emoji itselft as the query
     *
     * @param serviceIds a {@link Map} of a collection of ids for better content delivery experience
     * @return {@link Call}<{@link EmojiResponse}>
     */
    @GET("tags?platform=android&type=emoji")
    Call<EmojiResponse> getEmojiTags(@QueryMap Map<String, String> serviceIds);

    /**
     * Retrieves a set of <b>GIFs</b> a.k.a {@link Result} representing those that are currently trending
     *
     * @param serviceIds       a {@link Map} of a collection of ids for better content delivery experience
     * @param limit            <b>bucket</b> size of each response
     * @param pos              <b>index</b> for where the first result should come from.  If <b>empty</b>, start at the first result
     * @param mediaFilter      one of the options from {@link MediaFilter}
     * @param aspectRatioRange one of the options from {@link AspectRatioRange}
     * @return {@link Call}<{@link TrendingGifResponse}>
     */
    @GET("trending")
    Call<TrendingGifResponse> getTrending(@QueryMap Map<String, String> serviceIds,
                                          @Query("limit") Integer limit,
                                          @Query("pos") String pos,
                                          @Query("media_filter") @MediaFilter.Value String mediaFilter,
                                          @Query("ar_range") String aspectRatioRange);

    /**
     * Retrieves a set of <b>terms</b> a.k.a {@link String} representing those that are currently trending
     *
     * @param serviceIds a {@link Map} of a collection of ids for better content delivery experience
     * @param limit      <b>bucket</b> size of each response
     * @return {@link Call}<{@link TrendingTermResponse}>
     */
    @GET("autocomplete?type=trending")
    Call<TrendingTermResponse> getTrending(@QueryMap Map<String, String> serviceIds,
                                           @Query("limit") Integer limit);

    /**
     * Retrieve gifs with specific ids
     *
     * @param serviceIds       a {@link Map} of a collection of ids for better content delivery experience
     * @param ids              a comma separated string containing a list of unique ids of the desired gifs
     * @param mediaFilter      one of the options from {@link MediaFilter}
     * @param aspectRatioRange one of the options from {@link AspectRatioRange}
     * @return {@link Call}<{@link GifsResponse}>
     */
    @GET("gifs")
    Call<GifsResponse> getGifs(@QueryMap Map<String, String> serviceIds,
                               @Query("ids") String ids,
                               @Query("media_filter") @MediaFilter.Value String mediaFilter,
                               @Query("ar_range") String aspectRatioRange);

    /**
     * Search
     * Takes in a tag, and a set of related and similar tags, represented as a Pivot object
     *
     * @param serviceIds a {@link Map} of a collection of ids for better content delivery experience
     * @param tag        initial term
     * @param limit      <b>bucket</b> size of each response
     * @return {@link Call}<{@link SearchSuggestionResponse}>
     */
    @GET("search_suggestions?platform=android")
    Call<SearchSuggestionResponse> getSearchSuggestions(@QueryMap Map<String, String> serviceIds,
                                                        @Query("tag") String tag,
                                                        @Query("limit") @IntRange(from = 1, to = 50) Integer limit);

    /**
     * Returns the set of gifs uploaded by the current user
     *
     * @param serviceIds  a {@link Map} of a collection of ids for better content delivery experience
     * @param userId      <b>id</b> of the user
     * @param accessToken login <b>token</b>
     * @return {@link Call}<{@link GifsResponse}>
     */
    @GET("user")
    Call<GifsResponse> getUserGifs(@QueryMap Map<String, String> serviceIds,
                                   @Query("id") String userId,
                                   @Query("access_token") String accessToken);

    @HEAD
    Call<Void> getImageSize(@Url String imageUrl);

    @GET("suggest")
Answer:     Call<Suggestions> getSuggestions(@QueryMap Map<String, String> serviceIds,